Package ivs :: Package spectra :: Module linelists
[hide private]
[frames] | no frames]

Source Code for Module ivs.spectra.linelists

  1  """ 
  2  Access atomic data 
  3   
  4  Mendelev's Table:: 
  5   
  6      1  H  Hydrogen   11 Na Natrium    21 Sc Scandium  31 Ga Gallium    41 Nb Niobium    51 Sb Antimony 
  7      2  He Helium     12 Mg Magnesium  22 Ti Titanium  32 Ge Germanium  42 Mo Molybdenum 52 Te Tellurium 
  8      3  Li Lithium    13 Al Aluminium  23 V  Vanadium  33 As Arsenic    43 Tc Technetium 53 I  Iodine 
  9      4  Be Beryllium  14 Si Silicon    24 Cr Chromium  34 Se Selenium   44 Ru Ruthenium  54 Xe Xenon 
 10      5  B  Boron      15 P  Phosphorus 25 Mn Manganese 35 Br Bromine    45 Rh Rhodium    55 Cs Caesium 
 11      6  C  Carbon     16 S  Sulfur     26 Fe Iron      36 Kr Krypton    46 Pd Palladium  56 Ba Barium 
 12      7  N  Nitrogen   17 Cl Chlorine   28 Ni Nickel    37 Rb Rubidium   47 Ag Silver     57 La Lanthanum 
 13      8  O  Oxygen     18 Ar Argon      27 Co Cobalt    38 Sr Strontium  48 Cd Cadmium    58 Ce Cerium 
 14      9  F  Fluorine   19 K  Potassium  29 Cu Copper    39 Y  Yttrium    49 In Indium     59 Pr Praseodymium 
 15      10 Ne Neon       20 Ca Calcium    30 Zn Zinc      40 Zr Zirconium  50 Sn Tin        60 Nd Neodymium 
 16   
 17      61 Pm Promethium 71 Lu Lutetium   81 Tl Thallium  91 Pa Protactinium 101 Md Mendelevium    111 Rg  Roentgenium 
 18      62 Sm Samarium   72 Hf Hafnium    82 Pb Lead      92 U  Uranium      102 No Nobelium       112 Uub Ununbium 
 19      63 Eu Europium   73 Ta Tantalum   83 Bi Bismuth   93 Np Neptunium    103 Lr Lawrencium     113 Uut Ununtrium 
 20      64 Gd Gadolinium 74 W  Tungsten   84 Po Polonium  94 Pu Plutonium    104 Rf Rutherfordium  114 Uuq Ununquadium 
 21      65 Tb Terbium    75 Re Rhenium    85 At Astatine  95 Am Americium    105 Db Dubnium        115 Uup Ununpentium 
 22      66 Dy Dysprosium 76 Os Osmium     86 Rn Radon     96 Cm Curium       106 Sg Seaborgium     116 Uuh Ununhexium 
 23      67 Ho Holmium    77 Ir Iridium    87 Fr Francium  97 Bk Berkelium    107 Bh Bohrium        118 Uuo Ununoctium 
 24      68 Er Erbium     78 Pt Platinum   88 Ra Radium    98 Cf Californium  108 Hs Hassium 
 25      69 Tm Thulium    79 Au Gold       89 Ac Actinium  99 Es Einsteinium  109 Mt Meitnerium 
 26      70 Yb Ytterbium  80 Hg Mercury    90 Th Thorium   100 Fm Fermium     110 Ds Darmstadtium 
 27   
 28  """ 
 29  import os 
 30  import logging 
 31  import numpy as np 
 32  import pylab as pl 
 33  from numpy import inf 
 34   
 35  from ivs import config 
 36  from ivs.inout import ascii 
 37  from ivs.aux import loggers 
 38   
 39  logger = logging.getLogger("SPEC.LINELIST") 
 40  logger.addHandler(loggers.NullHandler) 
 41   
 42  atomcode = ['X', 'H','He','Li','Be', 'B', 'C', 'N', 'O', 'F','Ne', 
 43                  'Na','Mg','Al','Si', 'P', 'S','Cl','Ar', 'K','Ca', 
 44                  'Sc','Ti', 'V','Cr','Mn','Fe','Ni','Co','Cu','Zn', 
 45                  'Ga','Ge','As','Se','Br','Kr','Rb','Sr', 'Y','Zr', 
 46                  'Nb','Mo','Tc','Ru','Rh','Pd','Ag','Cd','In','Sn', 
 47                  'Sb','Te', 'I','Xe','Cs','Ba','La','Ce','Pr','Nd', 
 48                  'Pm','Sm','Eu','Gd','Tb','Dy','Ho','Er','Tm','Yb', 
 49                  'Lu','Hf','Ta', 'W','Re','Os','Ir','Pt','Au','Hg', 
 50                  'Tl','Pb','Bi','Po','At','Rn','Fr','Ra','Ac','Th', 
 51                  'Pa', 'U','Np','Pu','Am','Cu','Bk','Cf','Es','Fm', 
 52                  'Md','No','Lr','Rf','Db','Sg','Bh','Hs','Mt','Ds', 
 53                  'Rg'] 
 54  roman = ['I','II','III','IV','V','VI','VII','VIII','IX','X','XI','XII','XIII'] 
 55   
 56   
 57   
 58  stellar = os.path.join('linelists/mask') 
 59   
 60  #{ Main functions 
 61   
62 -def VALD(elem=None,xmin=3200.,xmax=4800.,outputdir=None):
63 """ 64 Request linelists from VALD for each ion seperately within a specific wavelength range. 65 66 elem = an array of ions e.g. ['CI','OII'], xmin and xmax: wavelength range in which the spectral lines are searched, outputdir = output directory chosen by the user. 67 68 If no elements are given, this function returns all of them. 69 70 @param elem: list of ions 71 @type elem: list of str 72 """ 73 if elem is None: 74 files = sorted(config.glob('VALD_individual','VALD_*.lijnen')) 75 elem = [os.path.splitext(os.path.basename(ff))[0].split('_')[1] for ff in files] 76 77 all_lines = [] 78 for i in range(len(elem)): 79 print elem[i] 80 filename = config.get_datafile('VALD_individual','VALD_' + elem[i] + '.lijnen') 81 if not os.path.isfile(filename): 82 logger.info('No data for element ' + str(elem[i])) 83 return None 84 85 newwav,newexc,newep,newgf = np.loadtxt(filename).T 86 lines = np.rec.fromarrays([newwav,newexc,newep,newgf],names=['wavelength','ion','ep','gf']) 87 keep = (xmin<=lines['wavelength']) & (lines['wavelength']<=xmax) 88 if not hasattr(keep,'__iter__'): 89 continue 90 lines = lines[keep] 91 if len(lines) and outputdir is not None: 92 ascii.write_array(lines,outputdir + 'VALD_' + str(elem[i]) + '_' + str(xmin) + '_' + str(xmax) + '.dat',auto_width=True,header=True,formats=['%.3f','%.1f','%.3f','%.3f']) 93 elif len(lines): 94 all_lines.append(lines) 95 else: 96 logger.debug('No lines of ' + str(elem[i]) + ' in given wavelength range') 97 return np.hstack(all_lines)
98
99 -def get_lines(teff,logg,z=0,atoms=None,ions=None,wrange=(-inf,inf),\ 100 blend=0.0):
101 """ 102 Retrieve line transitions and strengths for a specific stellar type 103 104 Selection wavelength range in angstrom. 105 106 Ions should be a list of ions to include. This can either be a string or 107 a number 108 109 A lines is considerd a blend if the closest line is closer than C{blend} angstrom. 110 111 Returns record array with fields C{wavelength}, C{ion} and C{depth}. 112 113 Example usage: 114 115 Retrieve all Silicon lines between 4500 and 4600 for a B1V star. 116 117 >>> data = get_lines(20000,4.0,atoms=['Si'],wrange=(4500,4600)) 118 >>> p = pl.figure() 119 >>> p = pl.vlines(data['wavelength'],1,1-data['depth']) 120 121 See how the depth of the Halpha line varies wrt temperature: 122 123 >>> teffs = range(5000,21000,1000) + range(22000,32000,2000) + range(30000,50000,50000) 124 >>> depths = np.zeros((len(teffs),7)) 125 >>> for i,teff in enumerate(teffs): 126 ... data = get_lines(teff,5.0,ions=['HI'],wrange=(3800,7000)) 127 ... depths[i] = data['depth'] 128 129 >>> p = pl.figure();p = pl.title('Depth of Balmer lines (Halpha-Heta)') 130 >>> p = pl.plot(teffs,1-depths,'o-') 131 >>> p = pl.xlabel('Effective temperature');p = pl.grid() 132 133 """ 134 #-- get filepath 135 filename = 'mask.%d.%02d.p%02d'%(int(teff),int(logg*10),int(z)) 136 filename = config.get_datafile(stellar,filename) 137 #-- read in the data and extract relevant columns 138 data = ascii.read2recarray(filename,skip_lines=1,dtype=[('wavelength','f8'),('ion','f8'),('depth','f8'),('c3','f8'),('c4','f8'),('c5','f8')]) 139 data = pl.mlab.rec_drop_fields(data,['c3','c4','c5']) 140 data['wavelength'] *= 10. 141 #-- remove blends 142 if blend>0: 143 blends_left = np.hstack([0,np.diff(data['wavelength'])]) 144 blends_right= np.hstack([np.diff(data['wavelength']),1e10]) 145 keep = (blends_left>blend) & (blends_right>blend) 146 data = data[keep] 147 148 #-- only keep those transitions within a certain wavelength range 149 keep = (wrange[0]<=data['wavelength']) & (data['wavelength']<=wrange[1]) 150 data = data[keep] 151 #-- only keep those transitions that belong to certain ions or atoms 152 if atoms is not None or ions is not None: 153 keep = np.array(np.zeros(len(data)),bool) 154 else: 155 keep = np.array(np.ones(len(data)),bool) 156 if atoms is not None: 157 #-- convert all atoms to their number and select the appropriate ones 158 atoms = [(isinstance(atom,str) and atomcode.index(atom.title()) or atom) for atom in atoms] 159 for atom in atoms: 160 keep = keep | (np.abs(data['ion']-atom)<0.5) 161 if ions is not None: 162 #-- convert all ions to their number and select the appropriate ones 163 ions = [(isinstance(ion,str) and name2ioncode(ion) or ion) for ion in ions] 164 for ion in ions: 165 keep = keep | (np.abs(data['ion']-ion)<0.005) 166 167 return data[keep]
168 169 170 #} 171 172 #{ Convert ion codes to ion names and back 173
174 -def ioncode2name(ioncode):
175 """ 176 Convert 14.01 to SiII 177 """ 178 atom = int(np.floor(ioncode)) 179 ion = int(np.round((ioncode-atom)*100)) 180 return atomcode[atom]+roman[ion]
181
182 -def name2ioncode(name):
183 """ 184 Convert SiII to 14.01 185 """ 186 atomname,ionstage = splitname(name) 187 return atomcode.index(atomname) + roman.index(ionstage)/100.
188
189 -def splitname(name):
190 """ 191 Split SiII into Si and II 192 """ 193 atomname = '' 194 ionstage = '' 195 for char in name: 196 if not atomname or char.islower(): 197 atomname+=char 198 elif char.isupper(): 199 ionstage+=char 200 return atomname,ionstage
201 202 203 #} 204 205 206 if __name__=="__main__": 207 import doctest 208 doctest.testmod() 209 pl.show() 210