def test_add_component(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI Lya, Lyb lya = AbsLine(1215.670*u.AA) lya.analy['vlim'] = [-300.,300.]*u.km/u.s lya.attrib['z'] = 2.92939 lya.attrib['N'] = 1e17 / u.cm**2 lyb = AbsLine(1025.7222*u.AA) lyb.analy['vlim'] = [-300.,300.]*u.km/u.s lyb.attrib['z'] = lya.attrib['z'] abscomp = AbsComponent.from_abslines([lya,lyb]) abscomp.coord = radec # Instantiate abssys = GenericAbsSystem.from_components([abscomp]) # New component oi = AbsLine('OI 1302') oi.analy['vlim'] = [-300.,300.]*u.km/u.s oi.attrib['z'] = lya.attrib['z'] abscomp2 = AbsComponent.from_abslines([oi]) abscomp2.coord = radec # Standard assert abssys.add_component(abscomp2) # Fail abssys = GenericAbsSystem.from_components([abscomp]) abscomp2.vlim = [-400.,300.]*u.km/u.s assert not abssys.add_component(abscomp2) # Overlap assert abssys.add_component(abscomp2, overlap_only=True)
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)
def add_DLA(self,z, NHI=20.3,bval=30.*u.km/u.s, comment='None', model=True): """Generate a new DLA """ # Lya, Lyb dla_lines = [] # For convenience for trans in ['HI 1025', 'HI 1215']: iline = AbsLine(trans) iline.attrib['z'] = z iline.attrib['N'] = 10**NHI / u.cm**2 iline.attrib['b'] = bval iline.attrib['coord'] = SkyCoord(ra=0*u.deg,dec=0*u.deg) dla_lines.append(iline) # Generate system new_sys = DLASystem.from_abslines(dla_lines) #(0*u.deg,0*u.deg),z,None,NHI) new_sys.bval = bval # This is not standard, but for convenience new_sys.comment = comment new_sys.dla_lines = dla_lines # Also for convenience # Name self.count_dla += 1 new_sys.label = 'DLA_Sys_{:d}'.format(self.count_dla) # Add self.abssys_widg.add_fil(new_sys.label) self.abssys_widg.all_abssys.append(new_sys) self.abssys_widg.abslist_widget.item( len(self.abssys_widg.all_abssys)).setSelected(True) # Update self.llist['Plot'] = False # Turn off metal-lines if model: # For dealing with initialization self.update_model()
def stack_plot(self, inp, use_lines=None, ymnx=None, add_lines=None, **kwargs): """ Generate a stack plot of the key lines for a given COS-Halos system Parameters ---------- inp : int or tuple int -- Index of the cgm_abs list tuple -- (field,gal_id) add_lines : list, optional List of additional lines to plot """ # Init from linetools.analysis import plots as ltap if ymnx is None: ymnx=(-0.1,1.2) cgm_abs = self[inp] abs_lines = [] # Setup the lines (defaults to a key seto) if use_lines is None: use_lines = [1215.6700, 1025.7223, 1334.5323, 977.020, 1031.9261, 1037.6167, 1260.4221, 1206.500, 1393.7550, 2796.352]*u.AA if add_lines is not None: use_lines = list(use_lines.value) + add_lines use_lines.sort() use_lines = use_lines*u.AA for iline in use_lines: spec = self.load_bg_cos_spec(inp, iline) if spec is None: print('Skipping {:g}. Assuming no coverage'.format(iline)) aline = AbsLine(iline, closest=True) aline.analy['spec'] = spec aline.attrib['z'] = cgm_abs.galaxy.z abs_lines.append(aline) # Execute ltap.stack_plot(abs_lines, vlim=[-400., 400]*u.km/u.s, ymnx=ymnx, **kwargs)
def test_coincident_line(): # Init AbsLines line1 = AbsLine(1215.6700*u.AA) line2 = AbsLine('CII 1334') # expected errors # no limits set try: answer = line1.coincident_line(line2) except ValueError: pass # limit only for l1 line1.limits.set((1500,1510)*u.AA) try: answer = line1.coincident_line(line2) except ValueError: pass # now limit for l2 line2.limits.set((1509,1520)*u.AA) # expected overlap assert line1.coincident_line(line2) assert line2.coincident_line(line1) # not expected overlap line2.limits.set((1510.1,1520)*u.AA) assert not line1.coincident_line(line2) assert not line2.coincident_line(line1)
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.
def test_init_single_absline(): # Single AbsLine lya = AbsLine(1215.670*u.AA) lya.analy['vlim'] = [-300.,300.]*u.km/u.s lya.attrib['z'] = 2.92939 abscomp = AbsComponent.from_abslines([lya]) # Test assert abscomp.Zion[0] == 1 np.testing.assert_allclose(abscomp.zcomp,2.92939)
def dla_vary_NHI(outfil='Figures/dla_vary_NHI.pdf'): """ DLA profiles with NHI varying """ # Wavelength array for my 'perfect' instrument wave = np.linspace(1160., 1270., 20000) * u.AA vel = (wave-1215.67*u.AA)/(1215.67*u.AA) * const.c.to('km/s') # Lya line lya = AbsLine(1215.6700*u.AA) #lya.attrib['N'] = 10.**(13.6)/u.cm**2 lya.attrib['b'] = 30 * u.km/u.s lya.attrib['z'] = 0. aNHI = [20.3, 21., 21.5, 22.] # Start the plot xmnx = (-10000, 10000) ymnx = (0., 1.0) pp = PdfPages(outfil) fig = plt.figure(figsize=(8.0, 5.0)) plt.clf() gs = gridspec.GridSpec(1,1) # Lya line ax = plt.subplot(gs[0]) #ax.xaxis.set_minor_locator(plt.MultipleLocator(0.5)) #ax.xaxis.set_major_locator(plt.MultipleLocator(20.)) #ax.yaxis.set_minor_locator(plt.MultipleLocator(0.1)) #ax.yaxis.set_major_locator(plt.MultipleLocator(0.2)) ax.set_xlim(xmnx) ax.set_ylim(ymnx) ax.set_ylabel('Normalized Flux') ax.set_xlabel('Relative Velocity (km/s)') lw = 1.5 # Data for NHI in aNHI: lyai = copy.deepcopy(lya) lyai.attrib['N'] = 10**NHI / u.cm**2 f_obsi = ltav.voigt_from_abslines(wave, [lyai]) ax.plot(vel, f_obsi.flux, linewidth=lw, label=r'$\log N_{\rm HI} = $'+'{:0.2f}'.format(NHI)) # Legend legend = plt.legend(loc='lower left', scatterpoints=1, borderpad=0.3, handletextpad=0.3, fontsize='large', numpoints=1) xputils.set_fontsize(ax, 17.) # Layout and save print('Writing {:s}'.format(outfil)) plt.tight_layout(pad=0.2,h_pad=0.0,w_pad=0.4) plt.subplots_adjust(hspace=0) pp.savefig(bbox_inches='tight') plt.close() # Finish pp.close()
def test_ismatch(): # Test Simple kinematics abslin1 = AbsLine('NiII 1741', z=1.) abslin2 = AbsLine('NiII 1741', z=1.) # Run answer = abslin1.ismatch(abslin2) assert answer # Tuple too answer2 = abslin1.ismatch((1., abslin1.wrest)) assert answer2
def test_add_absline(): abscomp,_ = mk_comp('HI', zcomp=0.) abscomp.add_absline(AbsLine('HI 972'), chk_sep=False, chk_vel=False) with pytest.raises(ValueError): abscomp.add_absline(AbsLine('HI 949'), vtoler=-10) # failed addition bad_absline = AbsLine('CIV 1550') bad_absline.limits.set([500, 1000]*u.km/u.s) bad_absline.attrib['coord'] = SkyCoord(20,20, unit='deg') abscomp.add_absline(bad_absline)
def test_add_absline(): abscomp, _ = mk_comp('HI', zcomp=0.) abscomp.add_absline(AbsLine('HI 972'), chk_sep=False, chk_vel=False) with pytest.raises(ValueError): abscomp.add_absline(AbsLine('HI 949'), vtoler=-10) # failed addition bad_absline = AbsLine('CIV 1550') bad_absline.limits.set([500, 1000] * u.km / u.s) bad_absline.attrib['coord'] = SkyCoord(20, 20, unit='deg') abscomp.add_absline(bad_absline)
def test_transtabl(): # Init AbsLines abslines = [AbsLine(1215.6700*u.AA), AbsLine('CII 1334')] # tbl = ltlu.transtable_from_speclines(abslines) assert len(tbl) == 2 assert 'logN' in tbl.keys() # add keys tbl = ltlu.transtable_from_speclines(abslines, add_keys=['A', 'log(w*f)']) assert 'A' in tbl.keys()
def test_multi_components(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI Lya, Lyb lya = AbsLine(1215.670*u.AA) lya.analy['vlim'] = [-300.,300.]*u.km/u.s lya.attrib['z'] = 2.92939 lyb = AbsLine(1025.7222*u.AA) lyb.analy['vlim'] = [-300.,300.]*u.km/u.s lyb.attrib['z'] = lya.attrib['z'] abscomp = AbsComponent.from_abslines([lya,lyb]) abscomp.coord = radec # SiII SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans) iline.attrib['z'] = 2.92939 iline.analy['vlim'] = [-250.,80.]*u.km/u.s abslines.append(iline) # SiII_comp = AbsComponent.from_abslines(abslines) SiII_comp.coord = radec # Instantiate LLSsys = GenericAbsSystem.from_components([abscomp,SiII_comp]) # Test assert len(LLSsys._components) == 2
def test_aodm_absline(): # Init CIV 1548 abslin = AbsLine('CIV 1548', z=2.9304) # Set spectrum abslin.analy['spec'] = lsio.readspec( data_path('UM184_nF.fits')) # Fumagalli+13 MagE spectrum abslin.limits.set([6080.78, 6087.82] * u.AA) #abslin.analy['wvlim'] = [6080.78, 6087.82]*u.AA # abslin.measure_aodm() N, sig_N, flgN = [abslin.attrib[key] for key in ['N', 'sig_N', 'flag_N']] np.testing.assert_allclose(N.value, 76369981945649.38) assert N.unit == 1 / u.cm**2 assert flgN == 1 # Now velocity limits abslin.setz(2.92929) abslin.limits.set((-150., 150.) * u.km / u.s) # abslin.measure_aodm() N, sig_N, flgN = [abslin.attrib[key] for key in ['N', 'sig_N', 'flag_N']] np.testing.assert_allclose(N.value, 80410608889125.64) return
def test_list_of_abslines(): radec = SkyCoord(ra=123.1143*u.deg, dec=-12.4321*u.deg) # HI Lya, Lyb lya = AbsLine(1215.670*u.AA) lya.analy['vlim'] = [-300.,300.]*u.km/u.s lya.attrib['z'] = 2.92939 lyb = AbsLine(1025.7222*u.AA) lyb.analy['vlim'] = [-300.,300.]*u.km/u.s lyb.attrib['z'] = lya.attrib['z'] abscomp = AbsComponent.from_abslines([lya,lyb]) abscomp.coord = radec # SiII SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans) iline.attrib['z'] = 2.92939 iline.analy['vlim'] = [-250.,80.]*u.km/u.s abslines.append(iline) # SiII_comp = AbsComponent.from_abslines(abslines) SiII_comp.coord = radec # Instantiate gensys = GenericAbsSystem.from_components([abscomp,SiII_comp]) # Now the list abslines = gensys.list_of_abslines() # Test assert len(abslines) == 6 # Grab one line lyb = gensys.get_absline('HI 1025') np.testing.assert_allclose(lyb.wrest.value, 1025.7222) lyb = gensys.get_absline(1025.72*u.AA) np.testing.assert_allclose(lyb.wrest.value, 1025.7222)
def test_voigt_sngl_line(): # Wavelength array wave = np.linspace(3644, 3650, 100) * u.AA imn = np.argmin(np.abs(wave.value - 3647)) # HI line abslin = AbsLine(1215.670 * u.AA, z=2.) abslin.attrib['N'] = 10**14. / u.cm**2 abslin.attrib['b'] = 25. * u.km / u.s # Voigt vmodel = abslin.generate_voigt(wave=wave) np.testing.assert_allclose(vmodel.flux[imn].value, 0.05145500775919881)
def test_voigt_sngl_tau(): # Wavelength array wave = np.linspace(3644, 3650, 100)*u.AA imn = np.argmin(np.abs(wave.value-3647)) # HI line abslin = AbsLine(1215.670*u.AA, z=2.) abslin.attrib['N'] = 10**14./u.cm**2 abslin.attrib['b'] = 25.*u.km/u.s # Tau tau = lav.voigt_from_abslines(wave,abslin,ret='tau') np.testing.assert_allclose(tau[imn], 2.9681283001576779)
def test_voigt_sngl_tau(): # Wavelength array wave = np.linspace(3644, 3650, 100) * u.AA imn = np.argmin(np.abs(wave.value - 3647)) # HI line abslin = AbsLine(1215.670 * u.AA, z=2.) abslin.attrib['N'] = 10**14. / u.cm**2 abslin.attrib['b'] = 25. * u.km / u.s # Tau tau = lav.voigt_from_abslines(wave, abslin, ret='tau') np.testing.assert_allclose(tau[imn], 2.9681283001576779)
def test_voigt_sngl_line(): # Wavelength array wave = np.linspace(3644, 3650, 100)*u.AA imn = np.argmin(np.abs(wave.value-3647)) # HI line abslin = AbsLine(1215.670*u.AA, z=2.) abslin.attrib['N'] = 10**14./u.cm**2 abslin.attrib['b'] = 25.*u.km/u.s # Voigt vmodel = abslin.generate_voigt(wave=wave) np.testing.assert_allclose(vmodel.flux[imn].value,0.05145500775919881)
def test_measurekin_absline(): # Test Simple kinematics abslin = AbsLine('NiII 1741',z=2.307922) # Set spectrum abslin.analy['spec'] = lsio.readspec(data_path('PH957_f.fits')) abslin.limits.set([-70., 70.]*u.km/u.s) # Measure Kin abslin.measure_kin() np.testing.assert_allclose(abslin.attrib['kin']['Dv'].value, 75.) np.testing.assert_allclose(abslin.attrib['kin']['fedg'], 0.20005782376000183)
def test_failed_init(): with pytest.raises(ValueError): abslin = AbsLine(1215.700 * u.AA) with pytest.raises(ValueError): abslin = AbsLine('HI Ly99') with pytest.raises(ValueError): sline = SpectralLine.from_dict(dict(ltype='wrong ltype')) with pytest.raises(ValueError): sline = SpectralLine('wrong ltype', 1215.67 * u.AA) with pytest.raises(ValueError): sline = SpectralLine('Abs', dict(bad_trans='because I am dict, right?'))
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 by name abslin3 = AbsLine('CII 1334') np.testing.assert_allclose(abslin3.data['wrest'], 1334.5323 * u.AA)
def test_init_multi_absline(): # AbsLine(s) lya = AbsLine(1215.670*u.AA, z=2.92939) lya.limits.set([-300.,300.]*u.km/u.s) lyb = AbsLine(1025.7222*u.AA) lyb.setz(lya.z) lyb.limits.set([-300.,300.]*u.km/u.s) # Instantiate abscomp = AbsComponent.from_abslines([lya,lyb]) # Test assert len(abscomp._abslines) == 2 np.testing.assert_allclose(abscomp.zcomp,2.92939)
def test_init_multi_absline(): # AbsLine(s) lya = AbsLine(1215.670 * u.AA, z=2.92939) lya.limits.set([-300., 300.] * u.km / u.s) lyb = AbsLine(1025.7222 * u.AA) lyb.setz(lya.z) lyb.limits.set([-300., 300.] * u.km / u.s) # Instantiate abscomp = AbsComponent.from_abslines([lya, lyb]) # Test assert len(abscomp._abslines) == 2 np.testing.assert_allclose(abscomp.zcomp, 2.92939)
def test_dicts(): # Init HI Lya abslin = AbsLine(1215.6700*u.AA) adict = abslin.to_dict() assert isinstance(adict, dict) # Write #pdb.set_trace() ltu.savejson('tmp.json', adict, overwrite=True) # Read newdict = ltu.loadjson('tmp.json') newlin = SpectralLine.from_dict(newdict) assert newlin.name == 'HI 1215'
def si2_comp(radec): # SiII SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans) iline.attrib['z'] = 2.92939 iline.analy['vlim'] = [-250.,80.]*u.km/u.s abslines.append(iline) # SiII_comp = AbsComponent.from_abslines(abslines) SiII_comp.coord = radec # return SiII_comp
def test_todict_withjson(): radec = SkyCoord(ra=123.1143 * u.deg, dec=-12.4321 * u.deg) # HI Lya, Lyb lya = AbsLine(1215.670 * u.AA) lya.limits.set([-300., 300.] * u.km / u.s) lya.attrib['z'] = 2.92939 lya.attrib['coord'] = radec lyb = AbsLine(1025.7222 * u.AA) lyb.limits.set([-300., 300.] * u.km / u.s) lyb.attrib['z'] = lya.attrib['z'] lyb.attrib['coord'] = radec abscomp = AbsComponent.from_abslines([lya, lyb]) # Instantiate HIsys = LymanAbsSystem.from_components([abscomp]) # Dict adict = HIsys.to_dict() assert isinstance(adict, dict) # Verify it is JSON compatible (failing in Python 3) import io, json with io.open('tmp.json', 'w', encoding='utf-8') as f: f.write( unicode( json.dumps(adict, sort_keys=True, indent=4, separators=(',', ': '))))
def test_copy(): # Single AbsLine lya = AbsLine(1215.670*u.AA, z=2.92939) lya.analy['vlim'] = [-300.,300.]*u.km/u.s abscomp = AbsComponent.from_abslines([lya]) # Copy abscomp2 = abscomp.copy() # Checks attrs = vars(abscomp).keys() attrs2 = vars(abscomp2).keys() for attr in attrs: assert attr in attrs2 np.testing.assert_allclose(abscomp._abslines[0].z, abscomp2._abslines[0].z)
def mk_comp(ctype,vlim=[-300.,300]*u.km/u.s,add_spec=False, use_rand=True, add_trans=False, zcomp=2.92939): # Read a spectrum Spec if add_spec: xspec = lsio.readspec(lt_path+'/spectra/tests/files/UM184_nF.fits') else: xspec = None # AbsLines if ctype == 'HI': all_trans = ['HI 1215', 'HI 1025'] elif ctype == 'SiII': all_trans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] if add_trans: all_trans += ['SiII 1193'] abslines = [] for trans in all_trans: iline = AbsLine(trans) iline.attrib['z'] = zcomp if use_rand: rnd = np.random.rand() else: rnd = 0. iline.attrib['logN'] = 13.3 + rnd iline.attrib['sig_logN'] = 0.15 iline.attrib['flag_N'] = 1 iline.analy['spec'] = xspec iline.analy['vlim'] = vlim iline.analy['wvlim'] = iline.wrest * (1 + zcomp + ltu.give_dz(vlim, zcomp)) _,_ = ltaa.linear_clm(iline.attrib) # Loads N, sig_N abslines.append(iline) # Component abscomp = AbsComponent.from_abslines(abslines) return abscomp, abslines
def fill_lls_lines(self, bval=20. * u.km / u.s, do_analysis=1): """ Generate an HI line list for an LLS. Goes into self.lls_lines Now generates a component too. Should have it check for an existing HI component.. Parameters ---------- bval : float, optional Doppler parameter in km/s do_analysis : int, optional flag for analysis """ from linetools.lists import linelist as lll # May be replaced by component class (as NT desires) HIlines = lll.LineList('HI') self.lls_lines = [] Nval = 10**self.NHI / u.cm**2 for wrest in u.Quantity(HIlines._data['wrest']): aline = AbsLine(wrest, linelist=HIlines) # Attributes aline.attrib['N'] = Nval aline.attrib['b'] = bval aline.setz(self.zabs) aline.limits.set(self.vlim) aline.analy['do_analysis'] = do_analysis aline.attrib['coord'] = self.coord self.lls_lines.append(aline) # Generate a component (should remove any previous HI) self.add_component(AbsComponent.from_abslines(self.lls_lines))
def test_init_single_absline(): # Single AbsLine lya = AbsLine(1215.670 * u.AA, z=2.92939) lya.limits.set([-300., 300.] * u.km / u.s) lya.attrib['N'] = 1e12 / u.cm**2 lya.attrib['sig_N'] = [1e11] * 2 / u.cm**2 lya.attrib['flag_N'] = 1 abscomp = AbsComponent.from_abslines([lya]) # Test assert abscomp.Zion[0] == 1 assert len(abscomp.sig_N) == 2 assert np.isclose(abscomp.sig_logN[0], 0.04342945) assert isinstance(abscomp.sig_logN, np.ndarray) np.testing.assert_allclose(abscomp.zcomp, 2.92939)
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
def test_voigt_model(): from astropy.modeling import fitting # Wavelength array wave = np.linspace(3644, 3650, 100) * u.AA # HI line abslin = AbsLine(1215.670 * u.AA, z=2.) abslin.attrib['N'] = 10**14. / u.cm**2 abslin.attrib['b'] = 25. * u.km / u.s # Voigt vmodel = abslin.generate_voigt(wave=wave) vmodel.sig = 0.1 # Voigt fit abslin.analy['spec'] = vmodel abslin.limits.set([-100., 100] * u.km / u.s) abslin.measure_aodm(normalize=False) # Sets analysis pixels fitvoigt = lav.single_voigt_model(logN=np.log10(abslin.attrib['N'].value), b=abslin.attrib['b'].value, z=2., wrest=abslin.wrest.value, gamma=abslin.data['gamma'].value, f=abslin.data['f'], fwhm=3.) # Restrict parameter space fitvoigt.logN.min = 12. fitvoigt.b.min = 10. fitvoigt.z.min = 2. + -100. * (1 + 2.) / c_kms fitvoigt.z.max = 2. + 100 * (1 + 2.) / c_kms # Fit fitter = fitting.LevMarLSQFitter() parm = fitter(fitvoigt, vmodel.wavelength[abslin.analy['pix']].value, vmodel.flux[abslin.analy['pix']].value) assert np.abs(parm.logN.value - np.log10(abslin.attrib['N'].value)) < 0.1
def plot_absline(iinp,logN,b, show=True): """Plot an absorption line with N,b properties Parameters ---------- iinp : float or str Rest wavelength (Ang) or name of transition (e.g. CIV1548) logN : float Log10 column b : float Doppler parameter (km/s) show : bool Whether to display the plot (set False for running tests). Default True. """ import numpy as np from linetools.spectralline import AbsLine from astropy import units as u # Search for the closest absline if isinstance(iinp,basestring): aline = AbsLine(iinp, closest=True) else: aline = AbsLine(iinp*u.AA, closest=True) wrest = aline.wrest.value # Generate a fake wavelength array near the line wvoff = 50. # Ang dwv = wrest/100000. # Ang (echelle) wave = np.arange(wrest-wvoff, wrest+wvoff, dwv) # Generate spectrum with voigt aline.attrib['N'] = 10**logN * u.cm**-2 aline.attrib['b'] = b * u.km/u.s xspec = aline.generate_voigt(wave=wave*u.AA) # get the plotting limits # remove first and last pixels fl = xspec.flux.value[1:-2] ind = np.flatnonzero(fl < 1 - 0.1 * (1 - np.min(fl))) ind += 1 wmin = xspec.wavelength[max(0, ind[0] - 10)] wmax = xspec.wavelength[min(len(xspec.flux) - 1, ind[-1] + 10)] #import pdb; pdb.set_trace() xspec.constant_sig(0.1) # S/N = 10 per pix # Calculate EW aline.analy['spec'] = xspec aline.analy['wvlim'] = np.array([wrest-15., wrest+15])*u.AA aline.measure_ew() print(aline) print('EW = {:g}'.format(aline.attrib['EW'])) # Plot xspec.plot(xlim=(wmin.to(u.AA).value, wmax.to(u.AA).value), show=show)
def si2_comp(radec): # SiII SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans, z=2.92939) iline.attrib['coord'] = radec iline.limits.set([-250.,80.]*u.km/u.s) abslines.append(iline) # SiII_comp = AbsComponent.from_abslines(abslines) SiII_comp.logN = 15. SiII_comp.flag_N = 1 # return SiII_comp
def oi_comp(radec, vlim=[-250., 80.] * u.km / u.s, z=2.92939): # SiII OItrans = ['OI 1302'] abslines = [] for trans in OItrans: iline = AbsLine(trans, z=z, linelist=ism) iline.attrib['coord'] = radec iline.limits.set(vlim) abslines.append(iline) # OI_comp = AbsComponent.from_abslines(abslines, skip_synth=True) OI_comp.logN = 15. OI_comp.flag_N = 1 # return OI_comp
def test_parse_abslines(): # Init AbsLines abslines = [AbsLine(1215.6700*u.AA), AbsLine('CII 1334')] # wrest wrest_values = ltlu.parse_speclines(abslines, 'wrest') np.testing.assert_allclose(wrest_values[1], 1334.5323*u.AA) # EW EW_values = ltlu.parse_speclines(abslines, 'EW') np.testing.assert_allclose(EW_values[1].value, 0.) # data A_values = ltlu.parse_speclines(abslines, 'A') np.testing.assert_allclose(A_values[0].value, 626500000.0) # append None aux = ltlu.parse_speclines(abslines, 'wrong_attribute') assert aux[0] is None
def oi_comp(radec, vlim=[-250.,80.]*u.km/u.s, z=2.92939): # SiII OItrans = ['OI 1302'] abslines = [] for trans in OItrans: iline = AbsLine(trans, z=z, linelist=ism) iline.attrib['coord'] = radec iline.limits.set(vlim) abslines.append(iline) # OI_comp = AbsComponent.from_abslines(abslines, skip_synth=True) OI_comp.logN = 15. OI_comp.flag_N = 1 # return OI_comp
def si2_comp(radec): # SiII SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans, z=2.92939) iline.attrib['coord'] = radec iline.limits.set([-250., 80.] * u.km / u.s) abslines.append(iline) # SiII_comp = AbsComponent.from_abslines(abslines) SiII_comp.logN = 15. SiII_comp.flag_N = 1 # return SiII_comp
def test_rest_limits(): SiIItrans = ['SiII 1260', 'SiII 1304'] radec = SkyCoord(ra=1., dec=1., unit='deg') abslines = [] for kk, trans in enumerate(SiIItrans): iline = AbsLine(trans, z=1., linelist=ism) iline.attrib['coord'] = radec if kk == 0: iline.limits.set([-250., 80.] * u.km / u.s) else: iline.limits.set([-50., 180.] * u.km / u.s) abslines.append(iline) # comp = AbsComponent.from_abslines(abslines, chk_vel=False) comp.reset_limits_from_abslines() assert np.isclose(comp.vlim[1].value, 180.)
def setatomicdata(lines, precise=True, linelist=ilist): lam = np.zeros(len(lines)) fosc = np.zeros(len(lines)) gam = np.zeros(len(lines)) for i, ll in enumerate(lines): try: al = AbsLine(ll * u.AA, closest=True, linelist=linelist) lam[i] = al.data['wrest'].value fosc[i] = al.data['f'] gam[i] = al.data['gamma'].value except: idx = jbg.closest(adata['wrest'], ll) lam[i] = adata['wrest'][idx] fosc[i] = adata['f'][idx] gam[i] = adata['gamma'][idx] if ((abs(lam[i] - ll) > 0.01) & (precise == True)): idx = jbg.closest(vdata['wrest'], ll) try: lam[i] = vdata['wrest'][idx].value fosc[i] = vdata['f'][idx] gam[i] = vdata['gamma'][idx].value except: lam[i] = vdata['wrest'][idx] fosc[i] = vdata['f'][idx] gam[i] = vdata['gamma'][idx] return lam, fosc, gam
def test_stack_plot(show=False): abslin1 = AbsLine(1548.204 * u.AA) abslin2 = AbsLine('CIV 1550') # no spectrum first ltap.stack_plot([abslin1], show=show) # Set spectrum spec = ltsio.readspec(data_path('UM184_nF.fits')) # already normalized abslin1.analy['spec'] = spec abslin1.analy['wvlim'] = [6079.78, 6168.82] * u.AA abslin1.attrib['z'] = 2.92929 ltap.stack_plot([abslin1], show=show) # second line abslin2.analy['spec'] = spec abslin2.analy['wvlim'] = [6079.78, 6168.82] * u.AA abslin2.attrib['z'] = 2.92929 ltap.stack_plot([abslin1, abslin2], show=show)
def test_rest_limits(): SiIItrans = ['SiII 1260', 'SiII 1304'] radec = SkyCoord(ra=1., dec=1., unit='deg') abslines = [] for kk,trans in enumerate(SiIItrans): iline = AbsLine(trans, z=1., linelist=ism) iline.attrib['coord'] = radec if kk == 0: iline.limits.set([-250.,80.]*u.km/u.s) else: iline.limits.set([-50.,180.]*u.km/u.s) abslines.append(iline) # comp = AbsComponent.from_abslines(abslines, chk_vel=False) comp.reset_limits_from_abslines() assert np.isclose(comp.vlim[1].value, 180.)
def add_forest(self,inp,z): """Add a Lya/Lyb forest line """ forest = [] # NHI NHI_dict = {'6':12.,'7':13.,'8':14.,'9':15.} forest_NHI=NHI_dict[inp] # Lines for name in ['HI 1215','HI 1025', 'HI 972']: aline = AbsLine(name, linelist=self.llist[self.llist['List']], z=z) # Attributes aline.attrib['N'] = 10**forest_NHI * u.cm**-2 aline.attrib['b'] = 20.*u.km/u.s # Append forest.append(aline) # Append to forest lines self.all_forest.append(forest)
def fill_lls_lines(self, bval=20.*u.km/u.s, do_analysis=1): """ Generate an HI line list for an LLS. Goes into self.lls_lines Now generates a component too. Should have it check for an existing HI component.. Parameters ---------- bval : float, optional Doppler parameter in km/s do_analysis : int, optional flag for analysis """ from linetools.lists import linelist as lll # May be replaced by component class (as NT desires) HIlines = lll.LineList('HI') self.lls_lines = [] Nval = 10**self.NHI / u.cm**2 for lline in HIlines._data: aline = AbsLine(lline['wrest'], linelist=HIlines) # Attributes aline.attrib['N'] = Nval aline.attrib['b'] = bval aline.attrib['z'] = self.zabs aline.analy['vlim'] = self.vlim aline.analy['do_analysis'] = do_analysis aline.attrib['coord'] = self.coord self.lls_lines.append(aline) # Generate a component (should remove any previous HI) self.add_component(AbsComponent.from_abslines(self.lls_lines))
def test_voigt_model(): from astropy.modeling import fitting # Wavelength array wave = np.linspace(3644, 3650, 100)*u.AA # HI line abslin = AbsLine(1215.670*u.AA, z=2.) abslin.attrib['N'] = 10**14./u.cm**2 abslin.attrib['b'] = 25.*u.km/u.s # Voigt vmodel = abslin.generate_voigt(wave=wave) vmodel.sig = 0.1 # Voigt fit abslin.analy['spec'] = vmodel abslin.limits.set([-100.,100]*u.km/u.s) abslin.measure_aodm(normalize=False) # Sets analysis pixels fitvoigt = lav.single_voigt_model(logN=np.log10(abslin.attrib['N'].value), b=abslin.attrib['b'].value, z=2., wrest=abslin.wrest.value, gamma=abslin.data['gamma'].value, f=abslin.data['f'], fwhm=3.) # Restrict parameter space fitvoigt.logN.min = 12. fitvoigt.b.min = 10. fitvoigt.z.min = 2. + -100. * (1 + 2.) / c_kms fitvoigt.z.max = 2. + 100 * (1 + 2.) / c_kms # Fit fitter = fitting.LevMarLSQFitter() parm = fitter(fitvoigt,vmodel.wavelength[abslin.analy['pix']].value, vmodel.flux[abslin.analy['pix']].value) assert np.abs(parm.logN.value-np.log10(abslin.attrib['N'].value)) < 0.1
def fill_lls_lines(self, bval=20. * u.km / u.s): """ Generate an HI line list for an LLS. Goes into self.lls_lines Parameters ---------- bval : float (20.) Doppler parameter in km/s """ from linetools.lists import linelist as lll from linetools.spectralline import AbsLine # May be replaced by component class (as NT desires) HIlines = lll.LineList('HI') self.lls_lines = [] for lline in HIlines._data: aline = AbsLine(lline['wrest'], linelist=HIlines) # Attributes aline.attrib['N'] = self.NHI aline.attrib['b'] = bval aline.attrib['z'] = self.zabs # Could set RA and DEC too aline.attrib['RA'] = self.coord.ra aline.attrib['DEC'] = self.coord.dec self.lls_lines.append(aline)
def test_init_single_absline(): # Single AbsLine lya = AbsLine(1215.670 * u.AA, z=2.92939) lya.limits.set([-300., 300.] * u.km / u.s) abscomp = AbsComponent.from_abslines([lya]) # Test assert abscomp.Zion[0] == 1 np.testing.assert_allclose(abscomp.zcomp, 2.92939) print(abscomp)
def test_stack_plot(show=False): abslin1 = AbsLine(1548.204*u.AA) abslin2 = AbsLine('CIV 1550') # no spectrum first ltap.stack_plot([abslin1], show=show) # Set spectrum spec = ltsio.readspec(data_path('UM184_nF.fits')) # already normalized abslin1.analy['spec'] = spec abslin1.analy['wvlim'] = [6079.78, 6168.82]*u.AA abslin1.setz(2.92929) ltap.stack_plot([abslin1], show=show) # second line abslin2.analy['spec'] = spec abslin2.analy['wvlim'] = [6079.78, 6168.82]*u.AA abslin2.setz(2.92929) ltap.stack_plot([abslin1, abslin2], show=show) # now with a zref ltap.stack_plot([abslin1, abslin2], show=show, zref=2.928)
def test_synthesize_colm(): # Read a spectrum Spec xspec = lsio.readspec(lt_path+'/spectra/tests/files/UM184_nF.fits') # AbsLines SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans) iline.attrib['z'] = 2.92939 iline.analy['vlim'] = [-250.,80.]*u.km/u.s iline.analy['spec'] = xspec abslines.append(iline) # Component abscomp = AbsComponent.from_abslines(abslines) # Column abscomp.synthesize_colm(redo_aodm=True) # Test np.testing.assert_allclose(abscomp.logN,13.594447075294818)
def stack_plot(self, inp, use_lines=None, ymnx=None, add_lines=None, **kwargs): """ Generate a stack plot of the key lines for a given COS-Halos system Parameters ---------- inp : int or tuple int -- Index of the cgm_abs list tuple -- (field,gal_id) add_lines : list, optional List of additional lines to plot """ # Init from linetools.analysis import plots as ltap if ymnx is None: ymnx = (-0.1, 1.2) cgm_abs = self[inp] abs_lines = [] # Setup the lines (defaults to a key seto) if use_lines is None: use_lines = [ 1215.6700, 1025.7223, 1334.5323, 977.020, 1031.9261, 1037.6167, 1260.4221, 1206.500, 1393.7550, 2796.352 ] * u.AA if add_lines is not None: use_lines = list(use_lines.value) + add_lines use_lines.sort() use_lines = use_lines * u.AA for iline in use_lines: spec = self.load_bg_cos_spec(inp, iline) if spec is None: print('Skipping {:g}. Assuming no coverage'.format(iline)) aline = AbsLine(iline, closest=True) aline.analy['spec'] = spec aline.attrib['z'] = cgm_abs.galaxy.z abs_lines.append(aline) # Execute ltap.stack_plot(abs_lines, vlim=[-400., 400] * u.km / u.s, ymnx=ymnx, **kwargs)
def equiv_width_map(cube, varcube, measure_range, contwave1=None, contwave2=None, transition='MgII 2796', zsys=0.6942,normalize_continuum=True): """Calculate the equivalent width over some wavelength range """ from linetools.spectralline import AbsLine if normalize_continuum: normcube,signormcube = continuum_subtract(cube,varcube,contwave1,contwave2, normalize=True) else: normcube = cube signormcube = varcube al = AbsLine(transition,z = zsys) try: if measure_range[0].unit == u.AA: #import pdb; pdb.set_trace() al.limits.set(((measure_range[0]/al.wrest-1.).value,(measure_range[1]/al.wrest-1.).value)) elif measure_range.unit == (u.km/u.s): al.limits.set(measure_range) except: raise ValueError("measure_range should be a quantity with velocity or wavelength units") cubedims = np.shape(cube.data) ys = np.arange(cubedims[2]) xs = np.arange(cubedims[1]) grdTarr = np.array(np.meshgrid(xs, ys)).T rows = np.shape(grdTarr)[0] * np.shape(grdTarr)[1] spcoords = grdTarr.reshape(rows, 2) ewarr = np.zeros((cubedims[1],cubedims[2])) sigewarr = np.zeros((cubedims[1],cubedims[2])) for i,cc in enumerate(spcoords): spec = extract_spectrum(cube,cc) sigspec = extract_spectrum(varcube,cc) spec.sig = sigspec.flux al.analy['spec'] = spec al.measure_restew() ewarr[cc[0],cc[1]] = al.attrib['EW'].value sigewarr[cc[0],cc[1]] = al.attrib['sig_EW'].value return ewarr, sigewarr
def add_forest(self, inp, z): '''Add a Lya/Lyb forest line ''' from xastropy.igm.abs_sys.abssys_utils import GenericAbsSystem forest = GenericAbsSystem(zabs=z) # NHI NHI_dict = {'6': 12., '7': 13., '8': 14., '9': 15.} forest.NHI = NHI_dict[inp] # Lines for name in ['HI 1215', 'HI 1025', 'HI 972']: aline = AbsLine(name, linelist=self.llist[self.llist['List']]) # Attributes aline.attrib['N'] = forest.NHI aline.attrib['b'] = 20. * u.km / u.s aline.attrib['z'] = forest.zabs # Append forest.lines.append(aline) # Append to forest lines self.all_forest.append(forest)
def test_cog(): # Read a spectrum Spec xspec = lsio.readspec(lt_path+'/spectra/tests/files/UM184_nF.fits') # AbsLines SiIItrans = ['SiII 1260', 'SiII 1304', 'SiII 1526', 'SiII 1808'] abslines = [] for trans in SiIItrans: iline = AbsLine(trans) iline.attrib['z'] = 2.92939 iline.analy['vlim'] = [-250.,80.]*u.km/u.s iline.analy['spec'] = xspec abslines.append(iline) # Component abscomp = AbsComponent.from_abslines(abslines) # COG COG_dict = abscomp.cog(redo_EW=True) # Test np.testing.assert_allclose(COG_dict['logN'],13.693355878125537) np.testing.assert_allclose(COG_dict['sig_logN'],0.054323725737309987)
def test_dicts(): # Init HI Lya abslin = AbsLine(1215.6700*u.AA) abslin.analy['spec'] = 'tmp.fits' adict = abslin.to_dict() assert isinstance(adict, dict) # Write #pdb.set_trace() ltu.savejson('tmp.json', adict, overwrite=True) # Read newdict = ltu.loadjson('tmp.json') newlin = SpectralLine.from_dict(newdict) assert newlin.name == 'HI 1215' # Old dict for compatability newdict.pop('limits') newdict['analy']['vlim'] = [-150,150]*u.km/u.s newdict['attrib']['z'] = 0.5 tmp3 = SpectralLine.from_dict(newdict) assert newlin.name == 'HI 1215'
def add_forest(self,inp,z): '''Add a Lya/Lyb forest line ''' from xastropy.igm.abs_sys.abssys_utils import GenericAbsSystem forest = GenericAbsSystem((0.*u.deg,0.*u.deg), z, [-300.,300.]*u.km/u.s) # NHI NHI_dict = {'6':12.,'7':13.,'8':14.,'9':15.} forest.NHI=NHI_dict[inp] # Lines for name in ['HI 1215','HI 1025', 'HI 972']: aline = AbsLine(name, linelist=self.llist[self.llist['List']]) # Attributes aline.attrib['N'] = 10**forest.NHI * u.cm**-2 aline.attrib['b'] = 20.*u.km/u.s aline.attrib['z'] = forest.zabs # Append forest.lines.append(aline) # Append to forest lines self.all_forest.append(forest)