Exemplo n.º 1
0
def test_name_to_ion():
    Zion = ions.name_ion('Si II')
    assert Zion == (14,2)
    # bad input
    with pytest.raises(ValueError):
        aux = ions.name_ion(4)  # not a string
    # Deuterium
    aux = ions.name_ion('DI')
Exemplo n.º 2
0
def peroux06b():
    """Peroux, C. et al. 2006b, A&A, 450, 53
    SDSS J1323-0021
    Metal rich
    Metal columns copied by JXP from Table 1 
    Total NHI from damping wings
    """
    # Setup
    radec = '132323.78-002155.2'  # SDSS Name
    lls = LLSSystem(name='SDSSJ1323-0021_z0.716', radec=radec, zem=1.390,
        zabs=0.716, vlim=[-200., 200.]*u.km/u.s, NHI=20.21,
                    sig_NHI=np.array([0.20,0.20]))
    # Parse table file
    tab_fil = pyigm_path+"/data/LLS/Literature/peroux06b.tb1.ascii"
    with open(tab_fil,'r') as f:
        flines = f.readlines()
    ion_dict = {}
    for iline in flines:
        isplit = iline.split('\t')
        if len(isplit[0]) == 0:
            # Grab ions and init
            ions = isplit[3:10]
            for ion in ions:
                Zion = ltai.name_ion(ion)
                ion_dict[ion] = dict(clm=0., sig_clm=0.,flg_clm=1,Z=Zion[0],ion=Zion[1])
            continue
        # Column or sigma?
        if isplit[0][0] == 'N': # Column
            for kk,iis in enumerate(isplit[3:10]):
                ion = ions[kk]
                if iis[0] == '>':
                    ion_dict[ion]['flg_clm'] = 2
                    ion_dict[ion]['clm'] += float(iis[1:])
                elif iis[0] == '<':
                    pass
                elif iis[0] == '.':
                    pass
                else:
                    ion_dict[ion]['clm'] += float(iis)
        else: # Sigma
            for kk,iis in enumerate(isplit[3:10]):
                ion = ions[kk]
                if iis[0] == '.':
                    pass
                else:
                    ion_dict[ion]['sig_clm'] += float(iis)**2
    # Convert to log
    for ion in ions:
        N = ion_dict[ion]['clm']
        sig = np.sqrt(ion_dict[ion]['sig_clm'])
        #
        ion_dict[ion]['clm'] = np.log10(N)
        if ion_dict[ion]['flg_clm'] == 2:
            ion_dict[ion]['sig_clm'] = 0.
        else:
            ion_dict[ion]['sig_clm'] = sig/N/np.log(10)
    # Finish
    lls._ionN = pyiau.dict_to_ions(ion_dict)
    lls.Refs.append('Prx06b')
    return lls
Exemplo n.º 3
0
def peroux06b():
    """Peroux, C. et al. 2006b, A&A, 450, 53
    SDSS J1323-0021
    Metal rich
    Metal columns copied by JXP from Table 1 
    Total NHI from damping wings
    """
    # Setup
    radec = '132323.78-002155.2'  # SDSS Name
    lls = LLSSystem(name='SDSSJ1323-0021_z0.716', radec=radec, zem=1.390,
        zabs=0.716, vlim=[-200., 200.]*u.km/u.s, NHI=20.21,
                    sig_NHI=np.array([0.20,0.20]))
    # Parse table file
    tab_fil = pyigm_path+"/data/LLS/Literature/peroux06b.tb1.ascii"
    with open(tab_fil,'r') as f:
        flines = f.readlines()
    ion_dict = {}
    for iline in flines:
        isplit = iline.split('\t')
        if len(isplit[0]) == 0:
            # Grab ions and init
            ions = isplit[3:10]
            for ion in ions:
                Zion = ltai.name_ion(ion)
                ion_dict[ion] = dict(clm=0., sig_clm=0.,flg_clm=1,Z=Zion[0],ion=Zion[1])
            continue
        # Column or sigma?
        if isplit[0][0] == 'N': # Column
            for kk,iis in enumerate(isplit[3:10]):
                ion = ions[kk]
                if iis[0] == '>':
                    ion_dict[ion]['flg_clm'] = 2
                    ion_dict[ion]['clm'] += float(iis[1:])
                elif iis[0] == '<':
                    pass
                elif iis[0] == '.':
                    pass
                else:
                    ion_dict[ion]['clm'] += float(iis)
        else: # Sigma
            for kk,iis in enumerate(isplit[3:10]):
                ion = ions[kk]
                if iis[0] == '.':
                    pass
                else:
                    ion_dict[ion]['sig_clm'] += float(iis)**2
    # Convert to log
    for ion in ions:
        N = ion_dict[ion]['clm']
        sig = np.sqrt(ion_dict[ion]['sig_clm'])
        #
        ion_dict[ion]['clm'] = np.log10(N)
        if ion_dict[ion]['flg_clm'] == 2:
            ion_dict[ion]['sig_clm'] = 0.
        else:
            ion_dict[ion]['sig_clm'] = sig/N/np.log(10)
    # Finish
    lls._ionN = pyiau.dict_to_ions(ion_dict)
    lls.Refs.append('Prx06b')
    return lls
Exemplo n.º 4
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
    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:
        llist._data[cols].pprint(99999)
        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)
Exemplo n.º 5
0
def dict_to_ions(idict):
    """  Manipulate dict into an ion astropy Table

    Will likely be deprecated

    Parameters
    ----------
    idict : dict

    Returns
    -------
    table : astropy.Table

    """
    #  Could probably use add_row or dict instantiation
    table = None
    for ion in idict.keys():
        Zion = ltai.name_ion(ion)
        if table is None:
            tkeys = idict[ion].keys()
            lst = [[idict[ion][tkey]] for tkey in tkeys]
            table = Table(lst, names=tkeys)
            # Extra columns
            if 'Z' not in tkeys:
                table.add_column(Column([Zion[0]], name='Z'))
                table.add_column(Column([Zion[1]], name='ion'))
        else:
            tdict = idict[ion]
            tkeys = idict[ion].keys()
            if 'Z' not in tkeys:
                tdict['Z'] = Zion[0]
                tdict['ion'] = Zion[1]
            # Add
            table.add_row(tdict)
    # Finish
    try:  # Historical keys
        table.rename_column('clm', 'logN')
    except:
        pass
    else:
        table.rename_column('sig_clm', 'sig_logN')
        table.rename_column('flg_clm', 'flag_N')
    # Return
    return table
Exemplo n.º 6
0
def dict_to_ions(idict):
    """  Manipulate dict into an ion astropy Table

    Will likely be deprecated

    Parameters
    ----------
    idict : dict

    Returns
    -------
    table : astropy.Table

    """
    #  Could probably use add_row or dict instantiation
    table = None
    for ion in idict.keys():
        Zion = ltai.name_ion(ion)
        if table is None:
            tkeys = idict[ion].keys()
            lst = [[idict[ion][tkey]] for tkey in tkeys]
            table = Table(lst, names=tkeys)
            # Extra columns
            if 'Z' not in tkeys:
                table.add_column(Column([Zion[0]], name='Z'))
                table.add_column(Column([Zion[1]], name='ion'))
        else:
            tdict = idict[ion]
            tkeys = idict[ion].keys()
            if 'Z' not in tkeys:
                tdict['Z'] = Zion[0]
                tdict['ion'] = Zion[1]
            # Add
            table.add_row(tdict)
    # Finish
    try:  # Historical keys
        table.rename_column('clm', 'logN')
    except:
        pass
    else:
        table.rename_column('sig_clm', 'sig_logN')
        table.rename_column('flg_clm', 'flag_N')
    # Return
    return table
Exemplo n.º 7
0
def tumlinson11():
    """Tumlinson, J. et al. 2011, ApJ, 733, 111
    J1009+0713
    HST/COS
    Metal columns parsed from Table 1
    NHI from LL+Lyman series (uncertain)
    """
    # Grab ASCII file from ApJ
    tab_fil = pyigm_path+"/data/LLS/Literature/tumlinson11.tb1.ascii"
    url = 'http://iopscience.iop.org/0004-637X/733/2/111/suppdata/apj388927t1_ascii.txt'
    chk_fil = glob.glob(tab_fil)
    if len(chk_fil) > 0:
        tab_fil = chk_fil[0]
    else:
        print('LLSSurvey: Grabbing table file from {:s}'.format(url))
        f = urllib2.urlopen(url)
        with open(tab_fil, "wb") as code:
            code.write(f.read())
    # Setup
    radec = '100902.06+071343.8'  # From paper
    lls = LLSSystem(name='J1009+0713_z0.356', radec=radec, zem=0.456,
        zabs=0.3558, vlim=[-200., 250.]*u.km/u.s, NHI=18.4, 
        sig_NHI=np.array([0.41,0.41]))

    # Columns
    # Start with Table 3 (VPFIT)
    with open(tab_fil,'r') as f:
        flines1 = f.readlines()
    # Trim
    flines1 = flines1[18:]
    #
    ion_dict = {}
    line_dict = dict(OI='1302',OVI='1038',MgII='2803^b',SiII='1190',
        CaII='3934',FeII='2586')
    ion = None
    for iline in flines1:
        isplit = iline.split('\t')
        if ion=='FeIII': # Last line
            break
        # Ion
        is2 = isplit[0].split(' ')
        ion = is2[0]+is2[1]
        try:
            gdl = line_dict[ion]
        except:
            pass
            #print('Taking {:s}'.format(isplit[0]))
        else:
            if is2[2] != gdl:
                continue
        Zion = ltai.name_ion(ion)
        ion_dict[ion] = dict(logN=0., sig_logN=0., flag_N=0, Z=Zion[0],ion=Zion[1])
        # Combine components [could replace with SubSystems some day]
        for iis in isplit[1:-1]:
            # Upper limit
            if (iis.strip()[0] == '<') & (ion_dict[ion]['flag_N']==0):
                ion_dict[ion]['flag_N']=3
                ion_dict[ion]['logN']=float(iis[1:])
            elif (iis.strip()[0] == '>'): # Saturated
                ion_dict[ion]['flag_N']=2
                ion_dict[ion]['logN']=log_sum([ion_dict[ion]['logN'],float(iis[1:5])])
            elif iis.strip()[0] in ['.','<']:
                pass
            else:
                if ion_dict[ion]['flag_N']==2: # Add to saturated
                    ion_dict[ion]['logN']=log_sum([ion_dict[ion]['logN'],float(iis[0:4])])
                else:
                    ion_dict[ion]['flag_N']=1
                    obj = dict(logN=float(iis[0:4]),sig_logN=float(iis[-4:]),
                               flag_N=1)
                    # Add
                    flag,N,sig = ltaa.sum_logN(ion_dict[ion],obj)
                    ion_dict[ion]['logN']=N
                    ion_dict[ion]['sig_logN']=sig
    # Finish
    lls._ionN = pyiau.dict_to_ions(ion_dict)
    lls.Refs.append('Tum11')
    return lls
Exemplo n.º 8
0
def jenkins2005():
    """Jenkins, E. et al. 2005, ApJ, 2005, 623, 767
    PHL 1811
    HST/STIS, FUSE
    Metals parsed from Table 1
      OI taken from text
      Had to input error on columns by hand (JXP)
    Total NHI from Lyman series. see Fig 3
    M/H from O/H
    """
    # Grab ASCII file from ApJ
    tab_fil = pyigm_path+"/data/LLS/Literature/jenkins2005.tb1.ascii"
    chk_fil = glob.glob(tab_fil)
    if len(chk_fil) > 0:
        tab_fil = chk_fil[0]
    else:
        url = 'http://iopscience.iop.org/0004-637X/623/2/767/fulltext/61520.tb1.txt'
        print('LLSSurvey: Grabbing table file from {:s}'.format(url))
        f = urllib2.urlopen(url)
        with open(tab_fil, "wb") as code:
            code.write(f.read())
    # Setup
    radec = '215501.5152-092224.688'  # SIMBAD
    lls = LLSSystem(name='PHL1811_z0.081', radec=radec, zem=0.192,
        zabs=0.080923, vlim=[-100., 100.]*u.km/u.s, NHI=17.98, ZH=-0.19,
        sig_NHI=np.array([0.05,0.05]))
    lls.lines = []  # Probably not used

    # AbsLines
    ism = LineList('ISM')
    Nsig = {'C IV': 0.4, 'N II': 0.4, 'Si II': 0.05, 'Si IV': 0.25, 
        'S II': 0.2, 'Fe II': 0.12, 'H I': 0.05, 'S III': 0.06}

    # Parse Table
    with open(tab_fil,'r') as f:
        flines = f.readlines()
    ion_dict = {}
    for iline in flines:
        iline = iline.strip()
        if (len(iline) == 0): 
            continue
        # Split on tabs
        isplit = iline.split('\t')
        # Offset?
        ioff = 0
        if isplit[0][0] in ['1','2']:
            ioff = -1
        # Catch bad lines
        if (isplit[1+ioff][0:6] in ['1442.0','1443.7','1120.9']): # Skip goofy CII line and CII*
            continue
        if len(isplit[2+ioff]) == 0: 
            continue
        # Ion
        if (len(isplit[0].strip()) > 0) & (isplit[0][0] not in ['1','2']):
            ionc = isplit[0].strip()
            try:
                Zion = ltai.name_ion(ionc)
            except KeyError:
                pdb.set_trace()
        # Generate the Line
        try:
            newline = AbsLine(float(isplit[2+ioff])*u.AA,linelist=ism, closest=True)
        except ValueError:
            pdb.set_trace()
        newline.attrib['z'] = lls.zabs
        # Spectrum
        newline.analy['datafile'] = 'STIS' if 'S' in isplit[1] else 'FUSE'
        # EW
        try:
            EWvals = isplit[4+ioff].split(' ')
        except IndexError:
            pdb.set_trace()
        newline.attrib['EW'] = float(EWvals[0])*u.AA/1e3
        newline.attrib['sig_EW'] = float(EWvals[2])*u.AA/1e3
        newline.attrib['flag_EW'] = 1
        if len(isplit) < (5+ioff+1):
            continue
        # Colm?
        #xdb.set_trace()
        newline.attrib['sig_logN'] = 0.
        if (len(isplit[5+ioff].strip()) > 0) & (isplit[5+ioff].strip() != '\\ldots'):
            if isplit[5+ioff][0] == '\\':
                ipos = isplit[5+ioff].find(' ')
                newline.attrib['logN'] = float(isplit[5+ioff][ipos+1:])
                newline.attrib['flag_N'] = 2
            elif isplit[5+ioff][0] == '<':
                ipos = 0
                newline.attrib['logN'] = float(isplit[5+ioff][ipos+1:])
                newline.attrib['flag_N'] = 3
            elif isplit[5+ioff][0] == '1':
                try:
                    newline.attrib['logN'] = float(isplit[5+ioff][0:5])
                except ValueError:
                    pdb.set_trace()
                newline.attrib['flag_N'] = 1
                try:
                    newline.attrib['sig_logN'] = Nsig[ionc]
                except KeyError:
                    print('No error for {:s}'.format(ionc))
            else:
                raise ValueError('Bad character')
            # ion_dict
            ion_dict[ionc] = dict(clm=newline.attrib['logN'], sig_clm=newline.attrib['sig_logN'],
                flg_clm=newline.attrib['flag_N'], Z=Zion[0], ion=Zion[1])
        # Append
        lls.lines.append(newline)
    # Fix NI, OI
    ion_dict['O I']['clm'] = 14.47
    ion_dict['O I']['sig_clm'] = 0.05
    ion_dict['N I']['flg_clm'] = 3
    lls._ionN = pyiau.dict_to_ions(ion_dict)

    lls.Refs.append('Jen05')
    # Return
    return lls
Exemplo n.º 9
0
def dessauges09():
    '''Dessauges-Zavadsky et al. 2009, MNRAS, 396, L96
    SLLS with UVES
    Zn,Fe abundances from Table 1 from astro-ph (LateX) by JXP [AODM]
     Taken from the Zn/H and Fe/H assuming *no* ionization corrections
    RA/DEC from the 'other' name 
    ''' 
    # Solar abundances
    eZn = 4.63
    eFe = 7.45
    sol = [eFe,eZn]
    #
    all_lls = []
    # Table 1
    tab_fil = pyigm_path+"/data/LLS/Literature/dessauges09.tb1.ascii"
    with open(tab_fil,'r') as f:
        flines1 = f.readlines()
    # Trim the first few lines
    flines1 = flines1[3:]
    for iline in flines1:
        # Parse
        isplit = iline.split('&')
        # QSO
        if iline[0:2] == 'QS':
            # QSO, RA/DEC, zem
            qso = isplit[0][4:].strip()
            radec = isplit[1].strip()[1:].replace('$','')
            zem = float(isplit[3].strip())
        # NHI, zabs
        zabs = float(isplit[4].strip())
        is2 = isplit[6].strip()
        NHI = float(is2[1:6])
        sigNHI = np.array([float(is2[10:14])]*2)
        # name
        name = qso+'z_{:.3f}'.format(zabs) 
        lls = LLSSystem(name=name, radec=radec, vlim=[-500,500]*u.km/u.s,
            zem=zem, zabs=zabs, NHI=NHI, sig_NHI=sigNHI)
        # ADOM Columns
        ion_dict = {}
        for kk,ion in enumerate(['Fe II','Zn II']):
            Zion = ltai.name_ion(ion)
            is2 = isplit[7+kk].strip()
            if is2[0:2] == '$>':
                ion_dict[ion] = dict(sig_clm=0.,flg_clm=2,Z=Zion[0],ion=Zion[1])
                ion_dict[ion]['clm'] = float(is2[2:7]) + NHI - 12 + sol[kk]
            elif is2[0:2] == '$<':
                ion_dict[ion] = dict(sig_clm=0.,flg_clm=3,Z=Zion[0],ion=Zion[1])
                ion_dict[ion]['clm'] = float(is2[2:7]) + NHI - 12 + sol[kk]
            elif is2[0:2] == '..':
                pass
            else:
                ion_dict[ion] = dict(flg_clm=1,Z=Zion[0],ion=Zion[1])
                ion_dict[ion]['clm'] = float(is2[1:6]) + NHI - 12 + sol[kk]
                ion_dict[ion]['sig_clm'] = float(is2[10:14])
        #xdb.set_trace()
        # Finish
        lls._ionN = pyiau.dict_to_ions(ion_dict)
        lls.Refs.append('DZ09')
        all_lls.append(lls)

    # Return SLLS only
    fin_slls = [ills for ills in all_lls if ills.NHI < 20.3]
    return fin_slls
Exemplo n.º 10
0
def meiring09():
    '''Meiring et al. 2009, MNRAS, 393, 1513
    SLLS with Magellan
    Abundances from Table 3 from astro-ph (LateX) by JXP [AODM]
    RA/DEC from Table 1
    ''' 
    all_lls = []
    # Table 1
    tab_fil = pyigm_path+"/data/LLS/Literature/meiring09.tb1.ascii"
    with open(tab_fil,'r') as f:
        flines1 = f.readlines()
    # Grab RA/DEC
    qso_dict = {}
    for iline in flines1:
        if iline[0:3] in [' QS','\hl','$\\c', ' J2', '   ']:
            continue
        # Parse
        isplit = iline.split('&')
        #xdb.set_trace()
        if '$' in isplit[3].strip():
            isplit[3] = '-'+(isplit[3].strip())[3:]
        radec = isplit[2].strip()+isplit[3].strip()
        radec = radec.replace(':','')
        # zem
        zem = float(isplit[5].strip())
        # Save
        qso_dict[isplit[0].strip()] = dict(radec=radec,zem=zem,
                                           vlim=[-500,500.]*u.km/u.s)

    # Abundances (AODM)
    # Table 3
    tab_fil = pyigm_path+"/data/LLS/Literature/meiring09.tb3.ascii"
    with open(tab_fil,'r') as f:
        flines3 = f.readlines()
    #
    for iline in flines3:
        if iline[0:2] in ['\h','  ']:
            continue
        # Parse
        isplit = iline.split('&')
        # Ions
        if iline[0:2] == 'QS':
            ioncs = []
            Zions = []
            for iis in isplit[3:-1]: # Skipping HI
                # Parse
                #is2 = iis.split('\\')
                #ip2 = is2[2].find('}')
                ionc = iis.strip()
                # Zion
                Zion = ltai.name_ion(ionc)
                # Append
                ioncs.append(ionc)
                Zions.append(Zion)
            continue
        if iline[0] == 'Q':
            # QSO
            qso = isplit[0].strip()
            if qso[-1] in ['A','B','C']:
                qso = qso[0:-1]
            # zabs and name
            zabs = float(isplit[1].strip())
            qso_dict[qso]['name']=qso+'z_{:.3f}'.format(zabs) 
            qso_dict[qso]['zabs']=zabs
            # NHI
            is2 = isplit[2].strip()
            if is2[0] == '$':
                qso_dict[qso]['NHI'] = 99.99 # THROW OUT Q1436-0051B
                qso_dict[qso]['sig_NHI'] = np.array([0.,0.])
            else:
                qso_dict[qso]['NHI'] = float(is2[0:5])
                qso_dict[qso]['sig_NHI'] = np.array([float(is2[10:])]*2)
            #if qso_dict[qso]['NHI'] >= 20.3:
            #    print('Uh oh.  DLA')
            # Generate LLS
            lls = LLSSystem(**qso_dict[qso])
            continue
        else:
            # ADOM Columns
            ion_dict = {}
            for kk,iis in enumerate(isplit[3:-1]):
                is2 = iis.strip()
                if is2[0:3] == '$>$':
                    ion_dict[ioncs[kk]] = dict(sig_clm=0.,flg_clm=2,Z=Zions[kk][0],ion=Zions[kk][1])
                    ion_dict[ioncs[kk]]['clm'] = float(is2[3:])
                elif is2[0:3] == '$<$':
                    ion_dict[ioncs[kk]] = dict(sig_clm=0.,flg_clm=3,Z=Zions[kk][0],ion=Zions[kk][1])
                    ion_dict[ioncs[kk]]['clm'] = float(is2[3:])
                elif len(is2) == 0:
                    pass
                else:
                    ion_dict[ioncs[kk]] = dict(flg_clm=1,Z=Zions[kk][0],ion=Zions[kk][1])
                    ion_dict[ioncs[kk]]['clm'] = float(is2[0:5])
                    ion_dict[ioncs[kk]]['sig_clm'] = float(is2[10:])
            # Finish
            lls._ionN = pyiau.dict_to_ions(ion_dict)
            lls.Refs.append('Mei09')
            all_lls.append(lls)

    # Return SLLS only
    fin_slls = [ills for ills in all_lls if ills.NHI < 20.3]
    return fin_slls
Exemplo n.º 11
0
def meiring07():
    """Meiring et al. 2007, MNRAS, 376, 557
    SLLS with Magellan
    Abundances from Table 11 from astro-ph (LateX) by JXP [AODM]
    RA/DEC from Table 1
    """
    all_lls = []
    # Table 1
    tab_fil = pyigm_path+"/data/LLS/Literature/meiring07.tb1.ascii"
    with open(tab_fil,'r') as f:
        flines1 = f.readlines()
    # Grab RA/DEC
    qso_dict = {}
    for iline in flines1:
        if iline[0:2] in ['QS','\h','$\\', 'J2']:
            continue
        # Parse
        isplit = iline.split('&')
        if '-' not in isplit[3]:
            sgn = '+'
        else:
            sgn = ''
        radec = isplit[2].strip()+sgn+isplit[3].strip()
        radec = radec.replace(':','')
        # zem
        if isplit[0].strip() != 'Q0826-2230':
            zem = float(isplit[5].strip())
        else:
            zem = 0.911
        # Save
        qso_dict[isplit[0].strip()] = dict(radec=radec, zem=zem,
                                           vlim=[-500.,500]*u.km/u.s)
    # Abundances (AODM)
    # Table 11
    tab_fil = pyigm_path+"/data/LLS/Literature/meiring07.tb11.ascii"
    with open(tab_fil,'r') as f:
        flines11 = f.readlines()
    #
    for iline in flines11:
        if iline[0:2] in ['\h','  ']:
            continue
        # Parse
        isplit = iline.split('&')
        # Ions
        if iline[0:2] == 'QS':
            ioncs = []
            Zions = []
            for iis in isplit[3:-1]: # Skipping HI
                # Parse
                is2 = iis.split('\\')
                ip2 = is2[2].find('}')
                ionc = is2[1][2:].strip()+' '+is2[2][0:ip2].strip()
                # Zion
                Zion = ltai.name_ion(ionc)
                # Append
                ioncs.append(ionc)
                Zions.append(Zion)
            continue
        if iline[0] == 'Q':
            # QSO
            qso = isplit[0].strip()
            # zabs and name
            zabs = float(isplit[1].strip())
            qso_dict[qso]['name']=qso+'z_{:.3f}'.format(zabs) 
            qso_dict[qso]['zabs']=zabs
            # NHI
            is2 = isplit[2].strip()
            qso_dict[qso]['NHI'] = float(is2[0:5])
            #if qso_dict[qso]['NHI'] >= 20.3:
            #    print('Uh oh.  DLA')
            qso_dict[qso]['sig_NHI'] = np.array([float(is2[10:])]*2)
            # Generate LLS
            lls = LLSSystem(**qso_dict[qso])
            continue
        else:
            # ADOM Columns
            ion_dict = {}
            for kk,iis in enumerate(isplit[3:-1]):
                is2 = iis.strip()
                if is2[0:3] == '$>$':
                    ion_dict[ioncs[kk]] = dict(sig_clm=0.,flg_clm=2,Z=Zions[kk][0],ion=Zions[kk][1])
                    ion_dict[ioncs[kk]]['clm'] = float(is2[3:])
                elif is2[0:3] == '$<$':
                    ion_dict[ioncs[kk]] = dict(sig_clm=0.,flg_clm=3,Z=Zions[kk][0],ion=Zions[kk][1])
                    ion_dict[ioncs[kk]]['clm'] = float(is2[3:])
                elif len(is2) == 0:
                    pass
                else:
                    ion_dict[ioncs[kk]] = dict(flg_clm=1,Z=Zions[kk][0],ion=Zions[kk][1])
                    ion_dict[ioncs[kk]]['clm'] = float(is2[0:5])
                    ion_dict[ioncs[kk]]['sig_clm'] = float(is2[10:])
            # Finish
            lls._ionN = pyiau.dict_to_ions(ion_dict)
            lls.Refs.append('Mei07')
            all_lls.append(lls)

    # Return SLLS only
    fin_slls = [ills for ills in all_lls if ills.NHI < 20.3]
    return fin_slls
Exemplo n.º 12
0
def fig_sngl_cldy_model(sys, dpath=os.getenv('COSHALOS_DATA')+'/Cloudy/', ax=None, outfil=None,
                        lsz=15., show_sys=False):
    """ Compare columns between model and data
    """
    # Read
    fh5 = h5py.File(dpath+sys+'_emcee.hd5', 'r')
    ions = fh5['inputs']['ions'].value
    data = fh5['inputs']['data'].value
    fit = fh5['outputs']['best_fit'].value
    fh5.close()

    # IP values
    IPs = np.zeros(len(ions))
    for ii,ion in enumerate(ions):
        Zion = lai.name_ion(ion)
        elm = ELEMENTS[Zion[0]]
        IPs[ii] = elm.ionenergy[Zion[1]-1]
    #xdb.set_trace()
    resid = data[:,1].astype(float) - fit

    # Start the plot
    if outfil is not None:
        pp = PdfPages(outfil)
        plt.figure(figsize=(7, 7))
        plt.clf()
        gs = gridspec.GridSpec(1, 1)
        ax = plt.subplot(gs[0])

    # Axes
    #wvmnx = awvmnx[iuvq['instr']]
    #ax.yaxis.set_major_locator(plt.MultipleLocator(1.))
    ax.minorticks_on()
    xlim = (5., np.max(IPs)+4)
    ax.set_xlim(xlim)
    ylim = (-1., 1.)
    ax.set_ylim(ylim)

    # Labels
    ax.set_xlabel('IP (eV)', size=lsz)
    ax.set_ylabel(r'$\Delta \, \log \, N$', size=lsz)
    ax.xaxis.set_major_locator(plt.MultipleLocator(10.))

    # Values
    gdv = np.where(data[:,3].astype(int) == 0)[0]
    if len(gdv) > 0:
        ax.errorbar(IPs[gdv],resid[gdv], xerr=0, linestyle='None',
                    yerr=data[:,2].astype(float)[gdv], color='blue', marker='o')
    # Limits
    limsz = 50.
    ulim = np.where(data[:,3].astype(int) == -1)[0]
    ax.scatter(IPs[ulim],resid[ulim], color='red', marker='v', s=limsz)
    llim = np.where(data[:,3].astype(int) == -2)[0]
    ax.scatter(IPs[llim],resid[llim], color='green', marker='^', s=limsz)

    # Label
    for kk,ion in enumerate(ions):
        if (resid[kk] < ylim[1]) & (resid[kk] > ylim[0]):
            ax.text(IPs[kk]+1, resid[kk], ion, color='k', size=lsz)  # Only if on page
    if show_sys:
        ax.text(0.04, 0.04, sys, transform=ax.transAxes, size=lsz-1, ha='left')
                #bbox={'facecolor':'white'})

    #legend = plt.legend(loc='upper right', scatterpoints=1, borderpad=0.3,
    #                    handletextpad=0.3, fontsize='small', numpoints=1)
    ax.plot(xlim, [0.,0.], 'g:')

    # End
    xputils.set_fontsize(ax,lsz)
    if outfil is not None:
        print('Writing {:s}'.format(outfil))
        plt.tight_layout(pad=0.2,h_pad=0.,w_pad=0.1)
        pp.savefig()
        pp.close()
        plt.close()
Exemplo n.º 13
0
def fig_sngl_cldy_model(sys,
                        dpath=os.getenv('COSHALOS_DATA') + '/Cloudy/',
                        ax=None,
                        outfil=None,
                        lsz=15.,
                        show_sys=False):
    """ Compare columns between model and data
    """
    # Read
    fh5 = h5py.File(dpath + sys + '_emcee.hd5', 'r')
    ions = fh5['inputs']['ions'].value
    data = fh5['inputs']['data'].value
    fit = fh5['outputs']['best_fit'].value
    fh5.close()

    # IP values
    IPs = np.zeros(len(ions))
    for ii, ion in enumerate(ions):
        Zion = lai.name_ion(ion)
        elm = ELEMENTS[Zion[0]]
        IPs[ii] = elm.ionenergy[Zion[1] - 1]
    #xdb.set_trace()
    resid = data[:, 1].astype(float) - fit

    # Start the plot
    if outfil is not None:
        pp = PdfPages(outfil)
        plt.figure(figsize=(7, 7))
        plt.clf()
        gs = gridspec.GridSpec(1, 1)
        ax = plt.subplot(gs[0])

    # Axes
    #wvmnx = awvmnx[iuvq['instr']]
    #ax.yaxis.set_major_locator(plt.MultipleLocator(1.))
    ax.minorticks_on()
    xlim = (5., np.max(IPs) + 4)
    ax.set_xlim(xlim)
    ylim = (-1., 1.)
    ax.set_ylim(ylim)

    # Labels
    ax.set_xlabel('IP (eV)', size=lsz)
    ax.set_ylabel(r'$\Delta \, \log \, N$', size=lsz)
    ax.xaxis.set_major_locator(plt.MultipleLocator(10.))

    # Values
    gdv = np.where(data[:, 3].astype(int) == 0)[0]
    if len(gdv) > 0:
        ax.errorbar(IPs[gdv],
                    resid[gdv],
                    xerr=0,
                    linestyle='None',
                    yerr=data[:, 2].astype(float)[gdv],
                    color='blue',
                    marker='o')
    # Limits
    limsz = 50.
    ulim = np.where(data[:, 3].astype(int) == -1)[0]
    ax.scatter(IPs[ulim], resid[ulim], color='red', marker='v', s=limsz)
    llim = np.where(data[:, 3].astype(int) == -2)[0]
    ax.scatter(IPs[llim], resid[llim], color='green', marker='^', s=limsz)

    # Label
    for kk, ion in enumerate(ions):
        if (resid[kk] < ylim[1]) & (resid[kk] > ylim[0]):
            ax.text(IPs[kk] + 1, resid[kk], ion, color='k',
                    size=lsz)  # Only if on page
    if show_sys:
        ax.text(0.04,
                0.04,
                sys,
                transform=ax.transAxes,
                size=lsz - 1,
                ha='left')
        #bbox={'facecolor':'white'})

    #legend = plt.legend(loc='upper right', scatterpoints=1, borderpad=0.3,
    #                    handletextpad=0.3, fontsize='small', numpoints=1)
    ax.plot(xlim, [0., 0.], 'g:')

    # End
    xputils.set_fontsize(ax, lsz)
    if outfil is not None:
        print('Writing {:s}'.format(outfil))
        plt.tight_layout(pad=0.2, h_pad=0., w_pad=0.1)
        pp.savefig()
        pp.close()
        plt.close()
Exemplo n.º 14
0
def complist_from_table(table):
    """
    Returns a list of AbsComponents from an input astropy.Table.

    Parameters
    ----------
    table : Table
        Table with component information (each row must correspond
        to a component). Each column is expecting a unit when
        appropriate.

    Returns
    -------
    complist : list
        List of AbsComponents defined from the input table.

    Notes
    -----
    Mandatory column names: 'RA', 'DEC', 'ion_name', 'z_comp', 'vmin', 'vmax'
        These column are required.
    Special column names: 'name', 'comment', 'logN', 'sig_logN', 'flag_logN'
        These columns will fill internal attributes when corresponding.
        In order to fill in the Ntuple attribute all three 'logN', 'sig_logN', 'flag_logN'
        must be present. For convenience 'logN' and 'sig_logN' are expected to be floats
        corresponding to their values in np.log10(1/cm^2).

    Other columns: 'any_column_name'
        These will be added as attributes within the AbsComponent.attrib dictionary,
        with their respective units if given.

    """
    # Convert to QTable to handle units in individual entries more easily
    table = QTable(table)

    # mandatory and optional columns
    min_columns = ['RA', 'DEC', 'ion_name', 'z_comp', 'vmin', 'vmax']
    special_columns = ['name', 'comment', 'logN', 'sig_logN', 'flag_logN']
    for colname in min_columns:
        if colname not in table.keys():
            raise IOError(
                '{} is a mandatory column. Please make sure your input table has it.'
                .format(colname))

    #loop over rows
    complist = []
    for row in table:
        # mandatory
        coord = SkyCoord(row['RA'].to('deg').value,
                         row['DEC'].to('deg').value,
                         unit='deg')  # RA y DEC must both come with units
        Zion = name_ion(row['ion_name'])
        zcomp = row['z_comp']
        vlim = [row['vmin'].to('km/s').value, row['vmax'].to('km/s').value
                ] * u.km / u.s  # units are expected here too

        # special columns
        try:
            Ntuple = (row['flag_logN'], row['logN'], row['sig_logN']
                      )  # no units expected
        except KeyError:
            Ntuple = None
        try:
            comment = row['comment']
        except KeyError:
            comment = ''
        try:
            name = row['name']
        except KeyError:
            name = None

        # define the component
        comp = AbsComponent(coord,
                            Zion,
                            zcomp,
                            vlim,
                            Ntup=Ntuple,
                            comment=comment,
                            name=name)

        # other columns will be filled in comp.attrib dict
        for colname in table.keys():
            if (colname not in special_columns) and (colname
                                                     not in min_columns):
                kms_cols = ['b', 'sig_b']
                if colname in kms_cols:  # check units for parameters expected in velocity units
                    try:
                        val_aux = row[colname].to('km/s').value * u.km / u.s
                    except u.UnitConversionError:
                        raise IOError(
                            'If `{}` column is present, it must have velocity units.'
                            .format(colname))
                    comp.attrib[colname] = val_aux
                # parameters we do not care about units much
                else:
                    comp.attrib[colname] = row[colname]

        # append
        complist += [comp]
    return complist
Exemplo n.º 15
0
def test_name_to_ion():
	Zion = ions.name_ion('Si II')
	assert Zion == (14,2)
Exemplo n.º 16
0
def battisti12():
    '''Battisti, A. et al. 2012, ApJ, 744, 93
    HST/COS
    QSO info from Table 1
    Metal columns parsed from Table 3
    NHI from Lya
    '''
    all_lls = []
    # Grab ASCII files from ApJ
    tab_fils = [pyigm_path+"/data/LLS/Literature/battisti12.tb1.ascii",
                pyigm_path+"/data/LLS/Literature/battisti12.tb3.ascii"]
    urls = ['http://iopscience.iop.org/0004-637X/744/2/93/suppdata/apj413924t1_ascii.txt',
        'http://iopscience.iop.org/0004-637X/744/2/93/suppdata/apj413924t3_ascii.txt']
    for jj,tab_fil in enumerate(tab_fils):
        chk_fil = glob.glob(tab_fil)
        if len(chk_fil) > 0:
            tab_fil = chk_fil[0]
        else:
            url = urls[jj]
            print('LLSSurvey: Grabbing table file from {:s}'.format(url))
            f = urllib2.urlopen(url)
            with open(tab_fil, "wb") as code:
                code.write(f.read())
    # QSO info 
    with open(tab_fils[0],'r') as f:
        flines1 = f.readlines()
    # Grab RA/DEC
    all_idict = []
    for iline in flines1:
        if iline[0:2] != 'SD':
            continue
        # Parse
        isplit = iline.split('\t')
        name = isplit[0].split(' ')[1]
        radec = name[1:]
        zem = float(isplit[1].strip())
        zabs = float(isplit[2].strip())
        NHI = float(isplit[3].strip()[0:4])
        sigNHI = np.array([float(isplit[3].strip()[11:])]*2)
        # Save
        lls = LLSSystem(name=name,radec=radec,zem=zem,
            zabs=zabs,NHI=NHI,sig_NHI=sigNHI, vlim=[-500,500]*u.km/u.s)
        #
        all_lls.append(lls)
        all_idict.append({})

    # Abundances
    with open(tab_fils[1],'r') as f:
        flines3 = f.readlines()
    flines3 = flines3[5:]
    ion = None
    for iline in flines3:
        if ion == 'Ni II':
            break
        isplit = iline.split('\t')
        if isplit[0] == 'C II*': # Skipping CII*
            continue
        # ion
        ipos = -1
        while (isplit[0][ipos] not in ['I','V']):
            ipos -= 1
        ion = isplit[0][0:ipos+1+len(isplit[0])]
        Zion = ltai.name_ion(ion)
        # Loop on systems
        for kk,iis in enumerate(isplit[1:-1]):
            if iis.strip()[0] == '.':
                continue
            all_idict[kk][ion] = dict(Z=Zion[0], ion=Zion[1],sig_clm=0.)
            if iis[0] == '>':
                all_idict[kk][ion]['flg_clm'] = 2
                all_idict[kk][ion]['clm'] = float(iis[1:6])
            elif iis[0] == '<':
                all_idict[kk][ion]['flg_clm'] = 3
                all_idict[kk][ion]['clm'] = float(iis[1:])
            else:
                all_idict[kk][ion]['flg_clm'] = 1
                all_idict[kk][ion]['clm'] = float(iis[0:5])
                all_idict[kk][ion]['sig_clm'] = float(iis[-4:])

    # Return SLLS only
    for kk,lls in enumerate(all_lls):
        try:
            lls._ionN = pyiau.dict_to_ions(all_idict[kk])
        except ValueError:
            pdb.set_trace()
        lls.Refs.append('Bat12')
    fin_slls = [ills for ills in all_lls if ills.NHI < 20.3]
    return fin_slls
Exemplo n.º 17
0
def complist_from_table(table):
    """
    Returns a list of AbsComponents from an input Table.

    Parameters
    ----------
    table : QTable
        Table with component information (each row must correspond
        to a component). Each column is expecting a unit when
        appropriate.

    Returns
    -------
    complist : list
        List of AbsComponents defined from the input table.

    Notes
    -----
    Mandatory column names: 'RA', 'DEC', 'ion_name', 'z_comp', 'vmin', 'vmax'
        These column are required.
    Special column names: 'name', 'comment', 'logN', 'sig_logN', 'flag_logN'
        These columns will fill internal attributes when corresponding.
        In order to fill in the Ntuple attribute all three 'logN', 'sig_logN', 'flag_logN'
        must be present. For convenience 'logN' and 'sig_logN' are expected to be floats
        corresponding to their values in np.log10(1/cm^2).

    Other columns: 'any_column_name'
        These will be added as attributes within the AbsComponent.attrib dictionary,
        with their respective units if given.

    """
    # mandatory and optional columns
    min_columns = ['RA', 'DEC', 'ion_name', 'z_comp', 'vmin', 'vmax']
    special_columns = ['name', 'comment', 'logN', 'sig_logN', 'flag_logN']
    for colname in min_columns:
        if colname not in table.keys():
            raise IOError('{} is a mandatory column. Please make sure your input table has it.'.format(colname))

    #loop over rows
    complist = []
    for row in table:
        # mandatory
        coord = SkyCoord(row['RA'].to('deg').value, row['DEC'].to('deg').value, unit='deg')  # RA y DEC must both come with units
        Zion = name_ion(row['ion_name'])
        zcomp = row['z_comp']
        vlim =[row['vmin'].to('km/s').value, row['vmax'].to('km/s').value] * u.km / u.s  # units are expected here too

        # special columns
        try:
            Ntuple = (row['flag_logN'], row['logN'], row['sig_logN'])  # no units expected
        except KeyError:
            Ntuple = None
        try:
            comment = row['comment']
        except KeyError:
            comment = ''
        try:
            name = row['name']
        except KeyError:
            name = None

        # define the component
        comp = AbsComponent(coord, Zion, zcomp, vlim, Ntup=Ntuple, comment=comment, name=name)

        # other columns will be filled in comp.attrib dict
        for colname in table.keys():
            if (colname not in special_columns) and (colname not in min_columns):
                kms_cols = ['b', 'sig_b']
                if colname in kms_cols:  # check units for parameters expected in velocity units
                    try:
                        val_aux = row[colname].to('km/s').value * u.km / u.s
                    except u.UnitConversionError:
                        raise IOError('If `{}` column is present, it must have velocity units.'.format(colname))
                    comp.attrib[colname] = val_aux
                # parameters we do not care about units much
                else:
                    comp.attrib[colname] = row[colname]

        # append
        complist += [comp]
    return complist
Exemplo n.º 18
0
def tripp2005():
    '''Tripp, T. et al. 2005, ApJ, 2005, 619, 714
    PG 1216+069 (LLS in Virgo)
    HST/STIS, FUSE
    Metal columns parsed from Tables 2 and 3
    Total NHI from damping wings
    M/H from O/H
    '''
    # Grab ASCII files from ApJ
    tab_fils = [pyigm_path+"/data/LLS/tripp2005.tb3.ascii",
                pyigm_path+"/data/LLS/tripp2005.tb2.ascii"]
    urls = ['http://iopscience.iop.org/0004-637X/619/2/714/fulltext/60797.tb3.txt',
        'http://iopscience.iop.org/0004-637X/619/2/714/fulltext/60797.tb2.txt']
    for jj,tab_fil in enumerate(tab_fils):
        chk_fil = glob.glob(tab_fil)
        if len(chk_fil) > 0:
            tab_fil = chk_fil[0]
        else:
            url = urls[jj]
            print('LLSSurvey: Grabbing table file from {:s}'.format(url))
            f = urllib2.urlopen(url)
            with open(tab_fil, "wb") as code:
                code.write(f.read())
    # Setup
    radec = '121920.9320+063838.476'  # SIMBAD
    lls = LLSSystem(name='PG1216+069_z0.006', radec=radec, zem=0.3313,
        zabs=0.00632, vlim=[-100., 100.]*u.km/u.s, NHI=19.32, ZH=-1.6,
        sig_NHI=np.array([0.03, 0.03]))

    # Columns
    # Start with Table 3 (VPFIT)
    with open(tab_fils[0],'r') as f:
        flines3 = f.readlines()
    ion_dict = {}
    for iline in flines3:
        if (len(iline.strip()) == 0): 
            continue
        isplit = iline.split('\t')
        # Ion
        flg = 2
        if (len(isplit[0].strip()) > 0):# & (isplit[0][0] not in ['1','2']):
            ipos = isplit[0].find('1')
            ionc = isplit[0][0:ipos-1].strip()
            try:
                Zion = ltai.name_ion(ionc)
            except KeyError:
                pdb.set_trace()
            flg = 1
        # Column
        csplit = isplit[3].split(' ')
        clm = float(csplit[0])
        sig = float(csplit[2])
        if flg == 1:
            ion_dict[ionc] = dict(logN=clm, sig_logN=sig, flag_N=1,
                                  Z=Zion[0], ion=Zion[1])
        else:  # Add it in
            tmp_dict = dict(logN=clm, sig_logN=sig, flag_N=1, Z=Zion[0],
                            ion=Zion[1])
            flagN, logN, siglogN = ltaa.sum_logN(ion_dict[ionc], tmp_dict)
            ion_dict[ionc]['logN'] = logN
            ion_dict[ionc]['sig_logN'] = siglogN
    ions = ion_dict.keys()

    # Now Table 2 for the extras
    with open(tab_fils[1],'r') as f:
        flines2 = f.readlines()
    # Trim the first 10 lines
    flines2 = flines2[10:]
    # Loop
    for iline in flines2:
        isplit = iline.split('\t')
        #
        ionc = isplit[0].strip()
        if (len(ionc) == 0) or (ionc in ions):
            continue
        #
        Zion = ltai.name_ion(ionc)
        ion_dict[ionc] = dict(Z=Zion[0], ion=Zion[1], sig_logN=0.)
        if isplit[4][0] == '<':
            ion_dict[ionc]['logN'] = float(isplit[4][1:])
            ion_dict[ionc]['flag_N'] = 3
        else:
            raise ValueError('Should not get here')


    # Finish
    lls._ionN = pyiau.dict_to_ions(ion_dict)
    lls.Refs.append('Tri05')
    return lls
Exemplo n.º 19
0
    def available_transitions(self, wvlims, n_max=None, n_max_tuple=None, min_strength=1.):
        """ Find the strongest transitions in a wavelength interval.

        For a given wavelength range, wvlims = (wv_min, wv_max), this
        function retrieves the n_max_tuple strongest transitions per
        each ion species in the LineList available at such a
        wavelength range and having strength larger than min_strength.
        Strength is defined as log10(wrest * fosc * abundance). The output
        is sorted by strength of the strongest available transition
        per ion species.

        Parameters
        ----------
        wvlims : tuple of Quantity
            Wavelength range, e.g. wvlims = (1100 * u.AA, 3200 * u.AA)
        n_max : int, optional
            Maximum number of transitions retrieved when given,
            otherwise recover all of them
        n_max_tuple : int, optional
            Maximum number of transitions in a given ion species to
            retrieve. e.g., if Lyman series are all available, it will
            retrieve only up to Lyman gamma if
            n_max_tuple = 3. Otherwise it returns all of them
        min_strength : float, optional
            Minimum strength calculated from log10(wrest * fosc *
            abundance) In this way HI 1215 has 14.7 by definition.

        Returns
        -------
        dict (if only 1 transition found) or QTable (if > 1
        transitions are found) or None (if no transition is found)
        """
        # Init
        from linetools.abund.solar import SolarAbund
        from linetools.abund import ions as laions
        solar = SolarAbund()

        if all((isinstance(n, int) or (n is None)) for n in [n_max, n_max_tuple]):
            if (n_max is not None) and (n_max < 1):
                return None
        else:
            raise SyntaxError(
                'Both n_max and n_max_tuple must be integers when given!')
        if isinstance(min_strength, (float,int)):
            pass
        else:
            raise SyntaxError('min_strength must be a float value')

        # Identify unique ion_names (e.g. HI, CIV, CIII)
        # unique_ion_names = list(set([name.split(' ')[0] for name in self._data['name']]))
        # unique_ion_names = np.array(unique_ion_names)
        unique_ion_names = np.unique(
            [name.split(' ')[0] for name in self._data['name']])

        # obtain the strongest transition of a given unique ion species
        ion_name = []
        strength = []
        for ion in unique_ion_names:  # This loop is necessary to have a non trivial but convinient order in the final output
            # Abundance
            Zion = laions.name_ion(ion)
            if ion == 'DI':
                abundance = 12. - 4.8  # Approximate for Deuterium
            else:
                abundance = solar[Zion[0]]

            aux = self.strongest_transitions(
                ion, wvlims, n_max=1)  # only the strongest
            if aux is not None:
                if isinstance(aux, dict):  # this should always be True given n_max=1
                    name = aux['name']
                else:
                    name = aux['name'][0]
                ion_name += [name]
                strength += [np.log10(aux['wrest'].value *
                                      aux['f']) + abundance]
        if len(ion_name) == 0:
            # no matches
            return None

        # create Table
        unique = Table()
        unique.add_column(Column(data=ion_name, name='name'))
        unique.add_column(Column(data=strength, name='strength'))

        # get rid of those below the min_strength threshold
        cond = unique['strength'] >= min_strength
        unique = unique[cond]
        if len(unique) < 1:
            return None

        # sort by strength
        unique.sort(['strength'])
        unique.reverse()  # Table unique is now sorted by strength, with only
        # 1 entry per ion species

        # Create output data adding up to n_max_tuple per ion species
        for i, row in enumerate(unique):
            name = row['name']
            aux = self.strongest_transitions(name, wvlims, n_max=n_max_tuple)
            # need to deal with dict vs QTable format now
            if isinstance(aux, dict):
                aux = self.from_dict_to_qtable(aux)
            if i == 0:
                # convert to Table because QTable does not like vstack
                output = Table(aux)
            else:
                # vstack is only supported for Table()
                output = vstack([output, Table(aux)])
        # if len==1 return dict
        if len(output) == 1:
            name = output['name'][0]
            return self.__getitem__(name)
        else:  # n_max>1
            if n_max > 1:
                output = output[:n_max]
            if len(output) == 1:  # return dictionary
                name = output['name'][0]
                return self.__getitem__(name)
            else:
                return QTable(output)
Exemplo n.º 20
0
Arquivo: lls.py Projeto: nhmc/pyigm
    def get_ions(self, use_Nfile=False, idict=None, update_zvlim=True, linelist=None):
        """Parse the ions for each Subsystem

        And put them together for the full system
        Fills ._ionN with a QTable

        Parameters
        ----------
        idict : dict, optional
          dict containing the IonClms info
        use_Nfile : bool, optional
          Parse ions from a .clm file (JXP historical)
        update_zvlim : bool, optional
          Update zvlim from lines in .clm (as applicable)
        linelist : LineList
        """
        if idict is not None:
            # Manipulate for astropy Table
            #  Could probably use add_row or dict instantiation
            table = None
            for ion in idict.keys():
                Zion = ltai.name_ion(ion)
                if table is None:
                    tkeys = idict[ion].keys()
                    lst = [[idict[ion][tkey]] for tkey in tkeys]
                    table = Table(lst, names=tkeys)
                    # Extra columns
                    if 'Z' not in tkeys:
                        table.add_column(Column([Zion[0]], name='Z'))
                        table.add_column(Column([Zion[1]], name='ion'))
                else:
                    tdict = idict[ion]
                    tkeys = idict[ion].keys()
                    if 'Z' not in tkeys:
                        tdict['Z'] = Zion[0]
                        tdict['ion'] = Zion[1]
                    # Add
                    table.add_row(tdict)
            # Finish
            try:  # Historical keys
                table.rename_column('clm', 'logN')
            except:
                pass
            else:
                table.rename_column('sig_clm', 'sig_logN')
                table.rename_column('flg_clm', 'flag_N')
            self._ionN = table
        elif use_Nfile:
            # Subsystems
            if self.nsub > 0:  # This speeds things up (but is rarely used)
                linelist = LineList('ISM')
            for lbl in self.subsys.keys():
                clm_fil = self.tree+self.subsys[lbl]._datdict['clm_file']
                # Parse .clm file
                self.subsys[lbl]._clmdict = igmau.read_clmfile(clm_fil, linelist=linelist)
                # Build components from lines
                components = igmau.build_components_from_abslines([], clmdict=self.subsys[lbl]._clmdict, coord=self.coord)
                # Update z, vlim
                if update_zvlim:
                    vmin,vmax = 9999., -9999.
                    for component in components:
                        vmin = min(vmin, component.vlim[0].value)
                        vmax = max(vmax, component.vlim[1].value)
                    self.subsys[lbl].zabs = self.subsys[lbl]._clmdict['zsys']
                    self.subsys[lbl].vlim = [vmin, vmax]*u.km/u.s
                # Read .ion file and fill in components
                ion_fil = self.tree+self.subsys[lbl]._clmdict['ion_fil']
                self.subsys[lbl]._indiv_ionclms = igmau.read_ion_file(ion_fil, components)
                # Parse .all file
                all_file = ion_fil.split('.ion')[0]+'.all'
                self.subsys[lbl].all_file=all_file #MF: useful to have
                _ = igmau.read_all_file(all_file, components=components)
                # Build table
                self.subsys[lbl]._ionN = igmau.iontable_from_components(components,ztbl=self.subsys[lbl].zabs)
                # Add to IGMSystem
                for comp in components:
                    self.add_component(comp)

            # Combine
            if self.nsub == 1:
                self._ionN = self.subsys['A']._ionN
                self._clmdict = self.subsys['A']._clmdict
                #xdb.set_trace()
            elif self.nsub == 0:
                raise ValueError('lls_utils.get_ions: Cannot have 0 subsystems..')
            else:
                self._ionN = self.subsys['A']._ionN
                self._clmdict = self.subsys['A']._clmdict
                warnings.warn('lls_utils.get_ions: Need to update multiple subsystems!! Taking A.')
        else:
            raise ValueError("Need an option in get_ions")