def init_conti_full(self): print("Initializing the continuum") spec = self.spec_widg.orig_spec spec.select = self.model_spec # Just in case, but this should already be the case # Full Model (LLS+continuum) self.full_model = XSpectrum1D.from_tuple( (spec.wavelength, np.ones(len(spec.wavelength)))) self.conti_dict = pycc.init_conti_dict( Norm=float(np.median(spec.flux.value)), piv_wv=1215. * (1 + self.zqso), #piv_wv2=915.*(1+zqso), igm='True') # Read Telfer and apply IGM if self.template is not None: tspec = lsi.readspec(self.template) # assume wavelengths tspec = XSpectrum1D.from_tuple( (tspec.wavelength.value * (1 + self.zqso), tspec.flux.value)) else: tspec = pycq.get_telfer_spec( zqso=self.zqso, igm=(self.conti_dict['igm'] == 'True')) # Rebin self.continuum = tspec.rebin(spec.wavelength) # Reset pivot wave self.conti_dict['piv_wv'] = 915. * (1 + self.zqso) #self.conti_dict['piv_wv'] = 1215.*(1+zqso) #self.conti_dict['piv_wv2'] = 915.*(1+zqso) self.base_continuum = self.continuum.flux self.update_conti() self.spec_widg.continuum = self.continuum
def test_from_tuple(): tmp = ascii.read(data_path('UM184.dat.gz'), names=['wave', 'flux', 'sig']) idl = dict(wave=np.array(tmp['wave']), flux=np.array(tmp['flux']), sig=np.array(tmp['sig'])) spec = XSpectrum1D.from_tuple((idl['wave'], idl['flux'], idl['sig'])) # np.testing.assert_allclose(spec.data['wave'][spec.select], idl['wave']) np.testing.assert_allclose(spec.data['sig'][spec.select], idl['sig'], atol=2e-3, rtol=0) assert spec.wavelength.unit == u.Unit('AA') # spec = XSpectrum1D.from_tuple((idl['wave'], idl['flux'])) np.testing.assert_allclose(spec.data['wave'][spec.select], idl['wave']) # continuum co = np.ones_like(idl['flux']) spec = XSpectrum1D.from_tuple((idl['wave'], idl['flux'], idl['sig'], co)) np.testing.assert_allclose(spec.data['wave'][spec.select], idl['wave']) co = None spec = XSpectrum1D.from_tuple((idl['wave'], idl['flux'], idl['sig'], co)) np.testing.assert_allclose(spec.data['wave'][spec.select], idl['wave'])
def test_errors(): # from_tuple try: spec = XSpectrum1D.from_tuple('this_is_not_a_tuple') except IOError: pass try: n_tuple = np.array([np.ones(5), np.ones(5)]), np.ones(5) spec = XSpectrum1D.from_tuple(n_tuple) except IOError: pass # wrong instances flux = [1, 2, 3] wave = [1, 2, 3] try: spec = XSpectrum1D(wave, flux) except IOError: pass #wrong shapes flux = np.ones(5) wave = np.array([1, 2, 3]) try: spec = XSpectrum1D(wave, flux) except IOError: pass try: spec = XSpectrum1D(wave, np.ones(len(wave)), sig=np.ones(2)) except IOError: pass try: spec = XSpectrum1D(wave, np.ones(len(wave)), co=np.ones(2), verbose=True) # test verbose here too except IOError: pass # wrong masking try: spec = XSpectrum1D(wave, np.ones(len(wave)), masking='wrong_masking') except IOError: pass #wrong units input try: spec = XSpectrum1D(wave, np.ones(len(wave)), units='not_a_dict') except IOError: pass try: spec = XSpectrum1D(wave, np.ones(len(wave)), units=dict(wrong_key=2)) except IOError: pass
def insert_dlas(sightline, overlap=False, rstate=None, slls=False, mix=False, high=False, noise=False): """ Insert a DLA into input spectrum Also adjusts the noise Will also add noise 'everywhere' if requested Parameters ---------- sightline:dla_cnn.data_model.sightline.Sightline object overlap: bool noise: bool, optional Returns ------- None """ #init if rstate is None: rstate = np.random.RandomState() spec = XSpectrum1D.from_tuple( (10**sightline.loglam, sightline.flux)) #generate xspectrum1d # Generate DLAs dlas = [] spec_dlas = [] zabslist = init_zabs(sightline, overlap) for zabs in zabslist: # Random NHI NHI = uniform_NHI(slls=slls, mix=mix, high=high) spec_dla = Dla((1 + zabs) * 1215.6701, NHI, '00' + str(jj)) if (slls or mix): dla = LLSSystem((sightline.ra, sightline.dec), zabs, None, NHI=NHI) else: dla = DLASystem((sightline.ra, sightline.dec), zabs, None, NHI) dlas.append(dla) spec_dlas.append(spec_dla) # Insert dlas to one sightline vmodel, _ = hi_model(dlas, spec, fwhm=3.) #add noise if noise: rand = rstate.randn(len(sightline.flux)) noise = rand * sightline.error * np.sqrt(1 - vmodel.flux.value**2) else: noise = 0 final_spec = XSpectrum1D.from_tuple( (vmodel.wavelength, spec.flux.value * vmodel.flux.value + noise)) #generate new sightline sightline.flux = final_spec.flux.value sightline.dlas = spec_dlas sightline.s2n = estimate_s2n(sightline)
def xspectrum1d_from_mpdaf_spec(sp, airvac='air'): """Gets a XSpectrum1D object in vacuum from an MPDAF Spectrum""" nomask = ~sp.mask fl = sp.data[nomask] er = np.sqrt(sp.var[nomask]) wv = sp.wave.coord()[nomask] meta = dict(airvac=airvac) spec = XSpectrum1D.from_tuple((wv, fl, er), meta=meta) spec.airtovac() spec2 = XSpectrum1D.from_tuple((spec.wavelength, fl, er)) return spec2
def test_wvmnx(): npix = 1000 # Without sig spec = XSpectrum1D.from_tuple((np.linspace(5000.,6000,npix), np.ones(npix))) assert spec.wvmin.value == 5000. assert spec.wvmax.value == 6000. # With sig spec = XSpectrum1D.from_tuple((np.linspace(5000.,6000,npix), np.ones(npix), np.ones(npix)*0.1)) assert spec.wvmin.value == 5000. assert spec.wvmax.value == 6000.
def test_mask_edge(): wave = 3000. + np.arange(1000) flux = np.ones_like(wave) sig = 0.1*np.ones_like(wave) sig[900:] = 0. sig[800:825] = 0. wave[900:] = 0. # WARNING, the data are sorted first! # spec = XSpectrum1D.from_tuple((wave,flux,sig), masking='edges') assert len(spec.wavelength) == 900 spec2 = XSpectrum1D.from_tuple((wave,flux,sig), masking='all') assert len(spec2.wavelength) == 875
def test_errors(): # from_tuple try: spec = XSpectrum1D.from_tuple('this_is_not_a_tuple') except IOError: pass try: n_tuple = np.array([np.ones(5), np.ones(5)]), np.ones(5) spec = XSpectrum1D.from_tuple(n_tuple) except IOError: pass # wrong instances flux = [1,2,3] wave = [1,2,3] try: spec = XSpectrum1D(wave, flux) except IOError: pass #wrong shapes flux = np.ones(5) wave = np.array([1,2,3]) try: spec = XSpectrum1D(wave, flux) except IOError: pass try: spec = XSpectrum1D(wave, np.ones(len(wave)), sig=np.ones(2)) except IOError: pass try: spec = XSpectrum1D(wave, np.ones(len(wave)), co=np.ones(2), verbose = True) # test verbose here too except IOError: pass # wrong masking try: spec = XSpectrum1D(wave, np.ones(len(wave)), masking = 'wrong_masking') except IOError: pass #wrong units input try: spec = XSpectrum1D(wave, np.ones(len(wave)), units = 'not_a_dict') except IOError: pass try: spec = XSpectrum1D(wave, np.ones(len(wave)), units =dict(wrong_key=2)) except IOError: pass
def test_masking(): wave = 3000. + np.arange(1000) flux = np.ones_like(wave) sig = 0.1 * np.ones_like(wave) sig[900:] = 0. sig[800:825] = 0. wave[900:] = 0. # WARNING, the data are sorted first! # spec = XSpectrum1D.from_tuple((wave, flux, sig), masking='edges') assert len(spec.wavelength) == 900 spec2 = XSpectrum1D.from_tuple((wave, flux, sig), masking='all') assert len(spec2.wavelength) == 875 spec3 = XSpectrum1D.from_tuple((wave, flux, sig), masking='none') assert len(spec3.wavelength) == len(wave)
def xspectrum1d_from_mpdaf_spec(sp, airvac='air'): """Gets a XSpectrum1D object in vacuum from an MPDAF Spectrum It does not take into account whether the wv is in air or vac anymore """ nomask = ~sp.mask fl = sp.data[nomask] er = np.sqrt(sp.var[nomask]) wv = sp.wave.coord()[nomask] meta = dict(airvac=airvac) spec = XSpectrum1D.from_tuple((wv, fl, er), meta=meta) #spec.airtovac() # print("\t Hola!!!!!!!!!!!!!!1") spec2 = XSpectrum1D.from_tuple((spec.wavelength, fl, er)) return spec2
def test_readwrite_meta_as_dicts(spec): sp = XSpectrum1D.from_tuple((np.array([5,6,7]), np.ones(3), np.ones(3)*0.1)) sp.meta['headers'][0] = dict(a=1, b='abc') sp2 = XSpectrum1D.from_tuple((np.array([8,9,10]), np.ones(3), np.ones(3)*0.1)) sp2.meta['headers'][0] = dict(c=2, d='efg') spec = ltsu.collate([sp,sp2]) # Write spec.write_to_fits(data_path('tmp.fits')) spec.write_to_hdf5(data_path('tmp.hdf5')) # Read and test newspec = io.readspec(data_path('tmp.hdf5')) assert newspec.meta['headers'][0]['a'] == 1 assert newspec.meta['headers'][0]['b'] == 'abc' newspec2 = io.readspec(data_path('tmp.fits')) assert 'METADATA' in newspec2.meta['headers'][0].keys()
def test_from_tuple(): idl = ascii.read(data_path('UM184.dat.gz'), names=['wave', 'flux', 'sig']) spec = XSpectrum1D.from_tuple((idl['wave'],idl['flux'],idl['sig'])) # np.testing.assert_allclose(spec.dispersion.value, idl['wave']) np.testing.assert_allclose(spec.sig, idl['sig'], atol=2e-3, rtol=0) assert spec.dispersion.unit == u.Unit('AA') # spec = XSpectrum1D.from_tuple((idl['wave'],idl['flux'])) np.testing.assert_allclose(spec.dispersion.value, idl['wave']) # continuum co = np.ones_like(idl['flux']) spec = XSpectrum1D.from_tuple((idl['wave'],idl['flux'],idl['sig'], co)) np.testing.assert_allclose(spec.dispersion.value, idl['wave'])
def get_telfer_spec(zqso=0., igm=False, fN_gamma=None, LL_flatten=True): '''Generate a Telfer QSO composite spectrum Parameters: ---------- zqso: float, optional Redshift of the QSO igm: bool, optional Include IGM opacity? [False] fN_gamma: float, optional Power-law evolution in f(N,X) LL_flatten: bool, optional Set Telfer to a constant below the LL? Returns: -------- telfer_spec: XSpectrum1D Spectrum ''' # Read telfer = ascii.read( xa_path+'/data/quasar/telfer_hst_comp01_rq.ascii', comment='#') scale = telfer['flux'][(telfer['wrest'] == 1450.)] telfer_spec = XSpectrum1D.from_tuple((telfer['wrest']*(1+zqso), telfer['flux']/scale[0])) # Observer frame # IGM? if igm is True: '''The following is quite experimental. Use at your own risk. ''' import multiprocessing from xastropy.igm.fN import model as xifm from xastropy.igm import tau_eff as xit fN_model = xifm.default_model() # Expanding range of zmnx (risky) fN_model.zmnx = (0.,5.) if fN_gamma is not None: fN_model.gamma = fN_gamma # Parallel igm_wv = np.where(telfer['wrest']<1220.)[0] adict = [] for wrest in telfer_spec.dispersion[igm_wv].value: tdict = dict(ilambda=wrest, zem=zqso, fN_model=fN_model) adict.append(tdict) # Run #xdb.set_trace() pool = multiprocessing.Pool(4) # initialize thread pool N threads ateff = pool.map(xit.map_etl, adict) # Apply telfer_spec.flux[igm_wv] *= np.exp(-1.*np.array(ateff)) # Flatten? if LL_flatten: wv_LL = np.where(np.abs(telfer_spec.dispersion/(1+zqso)-914.*u.AA)<3.*u.AA)[0] f_LL = np.median(telfer_spec.flux[wv_LL]) wv_low = np.where(telfer_spec.dispersion/(1+zqso)<911.7*u.AA)[0] telfer_spec.flux[wv_low] = f_LL # Return return telfer_spec
def compare_s2n(pp,lrdx_sciobj,pypit_boxfile, iso): '''Compare boxcar S/N ''' # Read/Load pypit_boxspec = lsio.readspec(pypit_boxfile) # Read LowRedux sig = np.sqrt(lrdx_sciobj['MASK_BOX']/(lrdx_sciobj['SIVAR_BOX'] + (lrdx_sciobj['MASK_BOX']==0))) lwrdx_boxspec = XSpectrum1D.from_tuple( (lrdx_sciobj['WAVE_BOX'], lrdx_sciobj['FLUX_BOX'], sig) ) # Plot plt.clf() fig = plt.figure(figsize=(16,7)) fig.suptitle("Instr={:s}, Setup={:s} :: Boxcar S/N for {:s} :: PYPIT ({:s})".format(iso[0], iso[1], iso[2], pypit.version), fontsize=18.) ax = plt.gca() ymax = np.median(pypit_boxspec.flux)*2. # PYPIT gdpy = pypit_boxspec.sig > 0. pys2n = pypit_boxspec.flux[gdpy]/pypit_boxspec.sig[gdpy] ax.plot(pypit_boxspec.dispersion[gdpy],pys2n, 'k-', drawstyle='steps', label='PYPIT') # LowRedux gdlx = lwrdx_boxspec.sig > 0. ax.plot(lwrdx_boxspec.dispersion[gdlx], lwrdx_boxspec.flux[gdlx]/lwrdx_boxspec.sig[gdlx], '-', color='blue', label='LowRedux') # Axes ax.set_xlim(np.min(pypit_boxspec.dispersion.value), np.max(pypit_boxspec.dispersion.value)) ax.set_ylim(0.,np.median(pys2n)*2.) ax.set_xlabel('Wavelength',fontsize=17.) ax.set_ylabel('S/N per pixel',fontsize=17.) # Legend legend = plt.legend(loc='upper right', borderpad=0.3, handletextpad=0.3, fontsize='x-large') # Finish plt.tight_layout(pad=0.2,h_pad=0.,w_pad=0.1,rect=[0, 0.03, 1, 0.95]) pp.savefig(bbox_inches='tight') plt.close()
def dump_bestfit(ppfit, outfile=None, z=0.): """ Create the bestfit in the observer frame and with vacuum wavelengths Parameters ---------- ppfit outfile Returns ------- bestfit: XSpectrum1D """ meta = dict(airvac='air', headers=[None]) # Spectrum bestfit = XSpectrum1D.from_tuple( (ppfit.lam * (1 + z), ppfit.bestfit / (1 + z)), meta=meta) # Convert to vacuum bestfit.airtovac() # Write if outfile is not None: bestfit.write(outfile) # Return return bestfit
def dummy_spectrum(s2n=10., rstate=None, seed=1234, wave=None): """ Parameters ---------- s2n seed wave Returns ------- spec : XSpectrum1D """ if rstate is None: rstate=np.random.RandomState(seed) if wave is None: wave = np.linspace(4000., 5000., 2000) # Create flux = np.ones_like(wave) sig = np.ones_like(wave) / s2n ispec = XSpectrum1D.from_tuple((wave,flux,sig)) # Noise and append spec = ispec.add_noise(rstate=rstate) flux, sig, mask = spec.data['flux'], spec.data['sig'], spec.data['flux'].mask ivar = utils.inverse(sig**2) return flux, ivar, mask
def test_get_local_s2n(): spec = XSpectrum1D.from_file(data_path('UM184_nF.fits')) wv0 = 4000 * u.AA s2n, sig_s2n = spec.get_local_s2n(wv0, 20, flux_th=0.9) np.testing.assert_allclose(s2n, 9.30119800567627, rtol=1e-5) np.testing.assert_allclose(sig_s2n, 1.0349911451339722, rtol=1e-5) # test with continuum spec.co = np.ones_like(spec.flux) s2n, sig_s2n = spec.get_local_s2n(wv0, 20, flux_th=0.9) np.testing.assert_allclose(s2n, 10.330545425415039, rtol=1e-5) np.testing.assert_allclose(sig_s2n, 0.4250050187110901, rtol=1e-5) # test errors # out of range with pytest.raises(IOError): spec.get_local_s2n(1215 * u.AA, 20) # sig not defined spec = XSpectrum1D.from_tuple((spec.wavelength, spec.flux)) with pytest.raises(ValueError): spec.get_local_s2n(wv0, 20) # bad shape for flux_th with pytest.raises(ValueError): spec.get_local_s2n(wv0, 20, flux_th=np.array([1, 2, 3, 4, 5])) # npix too big with pytest.raises(ValueError): spec.get_local_s2n(wv0, 1 + len(spec.wavelength))
def spec_from_array(wave, flux, sig, **kwargs): """ Make an XSpectrum1D from numpy arrays of wave, flux and sig Parameters ---------- If wave is unitless, Angstroms are assumed If flux is unitless, it is made dimensionless The units for sig and co are taken from flux. Return spectrum from arrays of wave, flux and sigma """ # Get rid of 0 wavelength good_wave = (wave > 1.0 * units.AA) wave, flux, sig = wave[good_wave], flux[good_wave], sig[good_wave] ituple = (wave, flux, sig) spectrum = XSpectrum1D.from_tuple(ituple, **kwargs) # Polish a bit -- Deal with NAN, inf, and *very* large values that will exceed # the floating point precision of float32 for var which is sig**2 (i.e. 1e38) bad_flux = np.any([ np.isnan(spectrum.flux), np.isinf(spectrum.flux), np.abs(spectrum.flux) > 1e30, spectrum.sig**2 > 1e10, ], axis=0) if np.sum(bad_flux): msgs.warn( "There are some bad flux values in this spectrum. Will zero them out and mask them (not ideal)" ) spectrum.data['flux'][spectrum.select][bad_flux] = 0. spectrum.data['sig'][spectrum.select][bad_flux] = 0. return spectrum
def test_get_local_s2n(): spec = XSpectrum1D.from_file(data_path('UM184_nF.fits')) wv0 = 4000 * u.AA s2n, sig_s2n = spec.get_local_s2n(wv0, 20, flux_th=0.9) np.testing.assert_allclose(s2n, 9.30119800567627, rtol=1e-5) np.testing.assert_allclose(sig_s2n, 1.0349911451339722, rtol=1e-5) # test with continuum spec.co = np.ones_like(spec.flux) s2n, sig_s2n = spec.get_local_s2n(wv0, 20, flux_th=0.9) np.testing.assert_allclose(s2n, 10.330545425415039, rtol=1e-5) np.testing.assert_allclose(sig_s2n, 0.4250050187110901, rtol=1e-5) # test errors # out of range with pytest.raises(IOError): spec.get_local_s2n(1215*u.AA, 20) # sig not defined spec = XSpectrum1D.from_tuple((spec.wavelength, spec.flux)) with pytest.raises(ValueError): spec.get_local_s2n(wv0, 20) # bad shape for flux_th with pytest.raises(ValueError): spec.get_local_s2n(wv0, 20, flux_th=np.array([1,2,3,4,5])) # npix too big with pytest.raises(ValueError): spec.get_local_s2n(wv0, 1 + len(spec.wavelength))
def test_readwrite_meta_as_dicts(spec): sp = XSpectrum1D.from_tuple((np.array([5, 6, 7]), np.ones(3), np.ones(3) * 0.1)) sp.meta['headers'][0] = dict(a=1, b='abc') sp2 = XSpectrum1D.from_tuple( (np.array([8, 9, 10]), np.ones(3), np.ones(3) * 0.1)) sp2.meta['headers'][0] = dict(c=2, d='efg') spec = ltsu.collate([sp, sp2]) # Write spec.write_to_fits(data_path('tmp.fits')) spec.write_to_hdf5(data_path('tmp.hdf5')) # Read and test newspec = io.readspec(data_path('tmp.hdf5')) assert newspec.meta['headers'][0]['a'] == 1 assert newspec.meta['headers'][0]['b'] == 'abc' newspec2 = io.readspec(data_path('tmp.fits')) assert 'METADATA' in newspec2.meta['headers'][0].keys()
def wfc3_continuum(wfc3_indx=None, zqso=0., wave=None, smooth=3., NHI_max=17.5, rstate=None): '''Use the WFC3 data + models from O'Meara+13 to generate a continuum Parameters ---------- wfc3_indx : int, optional Index of WFC3 data to use zqso : float, optional Redshift of the QSO wave : Quantity array, optional Wavelengths to rebin on smooth : float, optional Number of pixels to smooth on NHI_max : float, optional Maximum NHI for the sightline Returns ------- wfc3_continuum : XSpectrum1D of the continuum idx : int Index of the WFC3 spectrum used ''' # Random number if rstate is None: rstate = np.random.RandomState() # Open wfc3_models_hdu = fits.open(os.getenv('DROPBOX_DIR')+'XQ-100/LLS/wfc3_conti_models.fits') nwfc3 = len(wfc3_models_hdu)-1 # Load up models wfc_models = [] for ii in range(1,nwfc3-1): wfc_models.append( Table(wfc3_models_hdu[ii].data) ) # Grab a random one if wfc3_indx is None: need_c = True while(need_c): idx = rstate.randint(0,nwfc3-1) if wfc_models[idx]['TOTNHI'] > NHI_max: continue if wfc_models[idx]['QSO'] in ['J122836.05+510746.2', 'J122015.50+460802.4']: continue # These QSOs are NG need_c=False else: idx = wfc3_indx # Generate spectrum wfc_spec = XSpectrum1D.from_tuple( (wfc_models[idx]['WREST'].flatten()*(1+zqso), wfc_models[idx]['FLUX'].flatten()) ) # Smooth wfc_smooth = wfc_spec.gauss_smooth(fwhm=smooth) # Rebin? if wave is not None: wfc_rebin = wfc_smooth.rebin(wave) return wfc_rebin, idx else: return wfc_smooth, idx
def main(args): from scipy.io.idl import readsav from linetools.spectra.xspectrum1d import XSpectrum1D # Read lrdx_sky = readsav(args.lowrdx_sky) # Generate xspec = XSpectrum1D.from_tuple((lrdx_sky['wave_calib'], lrdx_sky['sky_calib'])) # Write xspec.write_to_fits(args.new_file)
def calculate_empirical_rms(spec, test=False): fl = spec.flux.value wv = spec.wavelength.value min_cond = ltu.is_local_minima(fl) max_cond = ltu.is_local_maxima(fl) min_local_inds = np.where(min_cond)[0] max_local_inds = np.where(max_cond)[0] interpolated_max = interp1d(wv[max_local_inds], fl[max_local_inds], kind='linear', bounds_error=False, fill_value=0) interpolated_min = interp1d(wv[min_local_inds], fl[min_local_inds], kind='linear', bounds_error=False, fill_value=0) # these are the envelopes fl_max = interpolated_max(wv) fl_min = interpolated_min(wv) # take the mid value fl_mid = 0.5 * (fl_max + fl_min) # reference flux # the idea here is that these will be the intrinsic rms per pixel (both are the same though) max_mean_diff = np.abs(fl_mid - fl_max) min_mean_diff = np.abs(fl_mid - fl_min) sigma = 0.5 * ( max_mean_diff + min_mean_diff ) # anyways these two differences are the same by definition if test: # fluxes wv_mins = wv[min_local_inds] wv_maxs = wv[max_local_inds] plt.figure() plt.plot(wv, fl, drawstyle='steps-mid') plt.plot(wv_mins, fl[min_local_inds], marker='o', color='r', label='Local minimum') plt.plot(wv_maxs, fl[max_local_inds], marker='o', color='green', label='Local maximum') plt.plot(wv, fl_mid, color='black', label='flux_mid') # sigmas plt.plot(wv, sigma, marker='o-', color='pink', label='Empirical sigma') plt.plot(wv, spec.sig.value, color='yellow', label='Original sigma') plt.legend() plt.show() return XSpectrum1D.from_tuple((wv, fl, sigma))
def dumb_spec(): """ Generate a dummy spectrum Returns ------- """ npix = 1000 dspec = XSpectrum1D.from_tuple((np.arange(npix)+5000., np.ones(npix), np.ones(npix))) # return dspec
def writeVPmodel(outfile, wave, fitpars, normflux, normsig): from astropy.table import Table model = voigtfunc(wave, fitpars) modeltab = Table([wave, model, normflux, normsig], names=['wavelength', 'model', 'normflux', 'normsig']) # modeltab.write(outfile, format='fits', overwrite=True) dummycont = np.ones(len(wave)) spec = XSpectrum1D.from_tuple((modeltab['wavelength'], modeltab['model'], modeltab['normsig'], dummycont)) spec.write_to_fits(outfile) print 'Voigt profile model written to:' print outfile
def test_copy(spec): # From existing spec2 = spec.copy() assert spec.wavelength[0] == spec2.wavelength[0] assert spec.flux[-1] == spec2.flux[-1] # wave = np.arange(3000., 6500) npix = len(wave) spect = XSpectrum1D.from_tuple((wave * u.AA, np.ones(npix))) specf = spect.copy() assert specf.sig_is_set is False
def writeVPmodel(outfile, wave, fitpars, normflux, normsig): from astropy.table import Table model = voigtfunc(wave, fitpars) modeltab = Table([wave, model, normflux, normsig], names=['wavelength', 'model', 'normflux', 'normsig']) # modeltab.write(outfile, format='fits', overwrite=True) dummycont = np.ones(len(wave)) spec = XSpectrum1D.from_tuple((modeltab['wavelength'], modeltab['model'], modeltab['normsig'], dummycont)) spec.write_to_fits(outfile) print('Voigt profile model written to:') print(outfile)
def test_copy(spec): # From existing spec2 = spec.copy() assert spec.wavelength[0] == spec2.wavelength[0] assert spec.flux[-1] == spec2.flux[-1] # wave = np.arange(3000., 6500) npix = len(wave) spect = XSpectrum1D.from_tuple((wave*u.AA,np.ones(npix))) specf = spect.copy() assert specf.sig_is_set is False
def test_from_tuple(): tmp = ascii.read(data_path('UM184.dat.gz'), names=['wave', 'flux', 'sig']) idl = dict(wave=np.array(tmp['wave']), flux=np.array(tmp['flux']), sig=np.array(tmp['sig'])) spec = XSpectrum1D.from_tuple((idl['wave'],idl['flux'], idl['sig'])) # np.testing.assert_allclose(spec.data['wave'][spec.select], idl['wave']) np.testing.assert_allclose(spec.data['sig'][spec.select], idl['sig'], atol=2e-3, rtol=0) assert spec.wavelength.unit == u.Unit('AA') # spec = XSpectrum1D.from_tuple((idl['wave'],idl['flux'])) np.testing.assert_allclose(spec.data['wave'][spec.select], idl['wave']) # continuum co = np.ones_like(idl['flux']) spec = XSpectrum1D.from_tuple((idl['wave'],idl['flux'],idl['sig'], co)) np.testing.assert_allclose(spec.data['wave'][spec.select], idl['wave']) co = None spec = XSpectrum1D.from_tuple((idl['wave'],idl['flux'],idl['sig'], co)) np.testing.assert_allclose(spec.data['wave'][spec.select], idl['wave'])
def get_dla(zabs, NHI, matrix_lam, matrix_flux, wvoff=60.): spec = XSpectrum1D.from_tuple((matrix_lam, matrix_flux)) if NHI < 20.3: dla = LLSSystem((0, 0), zabs, None, NHI=NHI) else: dla = DLASystem((0, 0), zabs, None, NHI) wvcen = (1 + zabs) * 1215.67 gd_wv = (spec.wavelength.value > wvcen - wvoff - 30) & (spec.wavelength.value < wvcen + wvoff + 30) co = 1.5 #np.mean(spec.flux[gd_wv])#amax lya, lines = hi_model(dla, spec, lya_only=True) return lya.wavelength[gd_wv], co * lya.flux[gd_wv]
def test_fluxmodel(): # Init lls = LLSSystem((0.*u.deg, 0.*u.deg), 2.5, None, NHI=17.9) # Fill LLS lines lls.fill_lls_lines() # Generate a spectrum wave = np.arange(3000., 6500) npix = len(wave) spec = XSpectrum1D.from_tuple((wave*u.AA,np.ones(npix))) # Model model = lls.flux_model(spec) np.testing.assert_allclose(model.flux[100].value,0.009424664763760516)
def load_spec_order(fname,objid=None,order=None,extract='OPT',flux=True): """ Loading single order spectrum from a PypeIt 1D specctrum fits file :param file: :param objid: :param order: :param extract: :param flux: :return: """ if objid is None: objid = 0 if order is None: msgs.error('Please specify which order you want to load') # read extension name into a list primary_header = fits.getheader(fname, 0) nspec = primary_header['NSPEC'] extnames = [primary_header['EXT0001']] * nspec for kk in range(nspec): extnames[kk] = primary_header['EXT' + '{0:04}'.format(kk + 1)] extnameroot = extnames[0] # Figure out which extension is the required data ordername = '{0:04}'.format(order) extname = extnameroot.replace('OBJ0000', objid) extname = extname.replace('ORDER0000', 'ORDER' + ordername) try: exten = extnames.index(extname) + 1 msgs.info("Loading extension {:s} of spectrum {:s}".format(extname, fname)) except: msgs.error("Spectrum {:s} does not contain {:s} extension".format(fname, extname)) spectrum = load.load_1dspec(fname, exten=exten, extract=extract, flux=flux) # Polish a bit -- Deal with NAN, inf, and *very* large values that will exceed # the floating point precision of float32 for var which is sig**2 (i.e. 1e38) bad_flux = np.any([np.isnan(spectrum.flux), np.isinf(spectrum.flux), np.abs(spectrum.flux) > 1e30, spectrum.sig ** 2 > 1e10, ], axis=0) # Sometimes Echelle spectra have zero wavelength bad_wave = spectrum.wavelength < 1000.0*units.AA bad_all = bad_flux + bad_wave ## trim bad part wave_out,flux_out,sig_out = spectrum.wavelength[~bad_all],spectrum.flux[~bad_all],spectrum.sig[~bad_all] spectrum_out = XSpectrum1D.from_tuple((wave_out,flux_out,sig_out), verbose=False) #if np.sum(bad_flux): # msgs.warn("There are some bad flux values in this spectrum. Will zero them out and mask them (not ideal)") # spectrum.data['flux'][spectrum.select][bad_flux] = 0. # spectrum.data['sig'][spectrum.select][bad_flux] = 0. return spectrum_out
def parse_UVES_popler(hdulist): """ Read a spectrum from a UVES_popler-style fits file. """ from linetools.spectra.xspectrum1d import XSpectrum1D hd = hdulist[0].header uwave = setwave(hd) * u.Angstrom co = hdulist[0].data[3] fx = hdulist[0].data[0] * co # Flux sig = hdulist[0].data[1] * co xspec1d = XSpectrum1D.from_tuple((uwave, fx, sig)) xspec1d.co = co return xspec1d
def writeVPmodel(outfile, wave, fitpars, normflux, normsig): from astropy.table import Table model = voigtfunc(wave, fitpars) modeltab = Table([wave, model, normflux, normsig], names=['wavelength', 'model', 'normflux', 'normsig']) dummycont = np.ones(len(wave)) spec = XSpectrum1D.from_tuple((modeltab['wavelength'], modeltab['model'], modeltab['normsig'], dummycont)) spec.write_to_fits(outfile)
def test_airtovac_andback(spec): npix = 1000 spec = XSpectrum1D.from_tuple((np.linspace(5000.,6000,npix), np.ones(npix))) # Airtovac spec.meta['airvac'] = 'air' spec.airtovac() # Test np.testing.assert_allclose(spec.wavelength[0].value, 5001.394869990007, rtol=1e-5) assert spec.meta['airvac'] == 'vac' # Vactoair spec.vactoair() np.testing.assert_allclose(spec.wavelength[0].value, 5000., rtol=1e-5) assert spec.meta['airvac'] == 'air'
def test_rebin(spec): # Add units funit = u.erg/u.s/u.cm**2 spec.units['flux'] = funit # Rebin new_wv = np.arange(3000., 9000., 5) * u.AA newspec = spec.rebin(new_wv, do_sig=True) # Test np.testing.assert_allclose(newspec.flux[1000].value, 1.0192499, rtol=1e-5) assert newspec.flux.unit == funit # Without sig spec_nosig = XSpectrum1D.from_tuple((spec.wavelength, spec.flux)) newspec = spec.rebin(new_wv) assert newspec.sig_is_set is False
def test_fluxmodel(): # Init lls = LLSSystem((0. * u.deg, 0. * u.deg), 2.5, None, NHI=17.9) # Fill LLS lines lls.fill_lls_lines() # Generate a spectrum wave = np.arange(3000., 6500) npix = len(wave) spec = XSpectrum1D.from_tuple((wave * u.AA, np.ones(npix))) # Model model = lls.flux_model(spec) np.testing.assert_allclose(model.flux[100].value, 0.009424664763760516, rtol=1e-5)
def compare_s2n(pp, lrdx_sciobj, pypit_boxfile, iso): '''Compare boxcar S/N ''' # Read/Load pypit_boxspec = lsio.readspec(pypit_boxfile) # Read LowRedux sig = np.sqrt(lrdx_sciobj['MASK_BOX'] / (lrdx_sciobj['SIVAR_BOX'] + (lrdx_sciobj['MASK_BOX'] == 0))) lwrdx_boxspec = XSpectrum1D.from_tuple( (lrdx_sciobj['WAVE_BOX'], lrdx_sciobj['FLUX_BOX'], sig)) # Plot plt.clf() fig = plt.figure(figsize=(16, 7)) fig.suptitle( "Instr={:s}, Setup={:s} :: Boxcar S/N for {:s} :: PYPIT ({:s})".format( iso[0], iso[1], iso[2], pypit.version), fontsize=18.) ax = plt.gca() ymax = np.median(pypit_boxspec.flux) * 2. # PYPIT gdpy = pypit_boxspec.sig > 0. pys2n = pypit_boxspec.flux[gdpy] / pypit_boxspec.sig[gdpy] ax.plot(pypit_boxspec.dispersion[gdpy], pys2n, 'k-', drawstyle='steps', label='PYPIT') # LowRedux gdlx = lwrdx_boxspec.sig > 0. ax.plot(lwrdx_boxspec.dispersion[gdlx], lwrdx_boxspec.flux[gdlx] / lwrdx_boxspec.sig[gdlx], '-', color='blue', label='LowRedux') # Axes ax.set_xlim(np.min(pypit_boxspec.dispersion.value), np.max(pypit_boxspec.dispersion.value)) ax.set_ylim(0., np.median(pys2n) * 2.) ax.set_xlabel('Wavelength', fontsize=17.) ax.set_ylabel('S/N per pixel', fontsize=17.) # Legend legend = plt.legend(loc='upper right', borderpad=0.3, handletextpad=0.3, fontsize='x-large') # Finish plt.tight_layout(pad=0.2, h_pad=0., w_pad=0.1, rect=[0, 0.03, 1, 0.95]) pp.savefig(bbox_inches='tight') plt.close()
def test_rebintwo(specr): # Add units funit = u.erg / u.s / u.cm**2 specr.units['flux'] = funit # Rebin new_wv = np.arange(3000., 9000., 5) * u.AA newspec = specr.rebin(new_wv, do_sig=True) # Test np.testing.assert_allclose(newspec.flux[1000].value, 0.999928, rtol=1e-5) assert newspec.flux.unit == funit # Without sig spec_nosig = XSpectrum1D.from_tuple((specr.wavelength, specr.flux)) newspec = specr.rebin(new_wv) assert newspec.sig_is_set is False
def get_telfer_spec(zqso=0., igm=False): '''Generate a Telfer QSO composite spectrum Paraemters: ---------- zqso: float, optional Redshift of the QSO igm: bool, optional Include IGM opacity? [False] Returns: -------- telfer_spec: XSpectrum1D Spectrum ''' # Read telfer = ascii.read(xa_path + '/data/quasar/telfer_hst_comp01_rq.ascii', comment='#') scale = telfer['flux'][(telfer['wrest'] == 1450.)] telfer_spec = XSpectrum1D.from_tuple( (telfer['wrest'] * (1 + zqso), telfer['flux'] / scale[0])) # Observer frame # IGM? if igm is True: '''The following is quite experimental. Use at your own risk. ''' import multiprocessing from xastropy.igm.fN import model as xifm from xastropy.igm import tau_eff as xit fN_model = xifm.default_model() # Expanding range of zmnx (risky) fN_model.zmnx = (0., 5.) # Parallel igm_wv = np.where(telfer['wrest'] < 1220.)[0] adict = [] for wrest in telfer_spec.dispersion[igm_wv].value: tdict = dict(ilambda=wrest, zem=zqso, fN_model=fN_model) adict.append(tdict) # Run #xdb.set_trace() pool = multiprocessing.Pool(4) # initialize thread pool N threads ateff = pool.map(xit.map_etl, adict) # Apply telfer_spec.flux[igm_wv] *= np.exp(-1. * np.array(ateff)) # Return return telfer_spec
def writeVPmodel(outfile, wave, fitpars, normflux, normsig): from astropy.table import Table model = voigtfunc(wave, fitpars) modeltab = Table( [wave, model, normflux, normsig], names=["wavelength", "model", "normflux", "normsig"], ) dummycont = np.ones(len(wave)) spec = XSpectrum1D.from_tuple((modeltab["wavelength"], modeltab["model"], modeltab["normsig"], dummycont)) spec.write_to_fits(outfile)
def get_telfer_spec(zqso=0., igm=False): '''Generate a Telfer QSO composite spectrum Paraemters: ---------- zqso: float, optional Redshift of the QSO igm: bool, optional Include IGM opacity? [False] Returns: -------- telfer_spec: XSpectrum1D Spectrum ''' # Read telfer = ascii.read( xa_path+'/data/quasar/telfer_hst_comp01_rq.ascii', comment='#') scale = telfer['flux'][(telfer['wrest'] == 1450.)] telfer_spec = XSpectrum1D.from_tuple((telfer['wrest']*(1+zqso), telfer['flux']/scale[0])) # Observer frame # IGM? if igm is True: '''The following is quite experimental. Use at your own risk. ''' import multiprocessing from xastropy.igm.fN import model as xifm from xastropy.igm import tau_eff as xit fN_model = xifm.default_model() # Expanding range of zmnx (risky) fN_model.zmnx = (0.,5.) # Parallel igm_wv = np.where(telfer['wrest']<1220.)[0] adict = [] for wrest in telfer_spec.dispersion[igm_wv].value: tdict = dict(ilambda=wrest, zem=zqso, fN_model=fN_model) adict.append(tdict) # Run #xdb.set_trace() pool = multiprocessing.Pool(4) # initialize thread pool N threads ateff = pool.map(xit.map_etl, adict) # Apply telfer_spec.flux[igm_wv] *= np.exp(-1.*np.array(ateff)) # Return return telfer_spec
def main(args): """ Runs the XSpecGui on an input file """ try: sobjs = specobjs.SpecObjs.from_fitsfile(args.file) except: # place holder until coadd data model is sorted out wave, flux, flux_ivar, flux_mask, meta_spec, head = general_spec_reader( args.file) spec = XSpectrum1D.from_tuple( (wave * u.AA, flux, np.sqrt(utils.inverse(flux_ivar))), masking='none') else: # List only? if args.list: print("Showing object names for input file...") for ii in range(len(sobjs)): name = sobjs[ii].NAME print("EXT{:07d} = {}".format(ii + 1, name)) return if args.obj is not None: exten = sobjs.name.index(args.obj) if exten < 0: msgs.error("Bad input object name: {:s}".format(args.obj)) else: exten = args.exten - 1 # 1-index in FITS file # Check Extraction if args.extract == 'OPT': if 'OPT_WAVE' not in sobjs[exten]._data.keys(): msgs.error( "Spectrum not extracted with OPT. Try --extract=BOX") spec = sobjs[exten].to_xspec1d(extraction=args.extract, fluxed=args.flux) # Setup app = QApplication(sys.argv) # Screen dimensions width = app.desktop().screenGeometry().width() scale = 2. * (width / 3200.) # Launch gui = XSpecGui(spec, screen_scale=scale) gui.show() app.exec_()
def main() : parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('lowrdx_sky', type = str, default = None, help = 'LowRedux Sky Spectrum (IDL save file)') parser.add_argument('new_file', type = str, default = None, help = 'PYPIT FITS sky spectrum') args = parser.parse_args() # Read lrdx_sky = readsav(args.lowrdx_sky) # Generate xspec = XSpectrum1D.from_tuple((lrdx_sky['wave_calib'], lrdx_sky['sky_calib'])) # Write xspec.write_to_fits(args.new_file)
def one_d_coadd(spectra, smask, weights, debug=False, **kwargs): """ Performs a weighted coadd of the spectra in 1D. Parameters ---------- spectra : XSpectrum1D weights : ndarray Should be masked Returns ------- coadd : XSpectrum1D """ from linetools.spectra.xspectrum1d import XSpectrum1D # Setup fluxes, sigs, wave = unpack_spec(spectra) variances = (sigs > 0.) * sigs**2 inv_variances = (sigs > 0.) / (sigs**2 + (sigs == 0.)) # Sum weights mweights = np.ma.array(weights, mask=smask) sum_weights = np.ma.sum(mweights, axis=0).filled(0.) # Coadd new_flux = np.ma.sum(mweights * fluxes, axis=0) / (sum_weights + (sum_weights == 0.0).astype(int)) var = (variances != 0.0).astype(float) / ( inv_variances + (inv_variances == 0.0).astype(float)) new_var = np.ma.sum((mweights**2.) * var, axis=0) / ( (sum_weights + (sum_weights == 0.0).astype(int))**2.) # Replace masked values with zeros new_flux = new_flux.filled(0.) new_sig = np.sqrt(new_var.filled(0.)) # New obj (for passing around) new_spec = XSpectrum1D.from_tuple((wave, new_flux, new_sig), masking='none') if False: debugger.plot1d(wave, new_flux, new_sig) debugger.set_trace() # Return return new_spec
def parse_linetools_spectrum_format(hdulist): """ Parse an old linetools-format spectrum from an hdulist Parameters ---------- hdulist : FITS HDU list Returns ------- xspec1d : XSpectrum1D Parsed spectrum """ if 'WAVELENGTH' not in hdulist: pdb.set_trace() #spec1d = spec_read_fits.read_fits_spectrum1d( # os.path.expanduser(datfil), dispersion_unit='AA') xspec1d = XSpectrum1D.from_spec1d(spec1d) else: wave = hdulist['WAVELENGTH'].data * u.AA fx = hdulist['FLUX'].data # Error array if 'ERROR' in hdulist: sig = hdulist['ERROR'].data else: sig = None if 'CONTINUUM' in hdulist: co = hdulist['CONTINUUM'].data else: co = None xspec1d = XSpectrum1D.from_tuple((wave, fx, sig, co)) if 'METADATA' in hdulist[0].header: # import pdb; pdb.set_trace() # patch for reading continuum metadata; todo: should be fixed properly!!! if "contpoints" in hdulist[0].header['METADATA']: aux_s = hdulist[0].header['METADATA'] if aux_s.endswith("}\' /"): aux_s = aux_s[:-3] # delete these extra characters hdulist[0].header['METADATA'] = aux_s xspec1d.meta.update(json.loads(hdulist[0].header['METADATA'])) return xspec1d
def compose_model(spec, filelist, outfile): ''' Generates full-model spectrum (XSpectrum1D) from a set of joebvp output files and writes out a file with the spectrum. Parameters ---------- spec : string or XSpectrum1D The spectrum to be fitted with the input lines filelist : list of strings or str This should be a list containing the names of VP input files or a string referring to a file simply listing the input files. See stevebvpfit.readpars for details of file format outfile : str Name of model spectrum output file ''' from joebvp import stevebvpfit ### Deal with alternate input types if isinstance(spec, str): specobj = readspec(spec) else: specobj = spec ### Load essentials from spectrum wave = specobj.wavelength.value normsig = specobj.sig.value / specobj.co.value cfg.wave = wave ### Concatenate all the parameter tables concatenate_line_tables(filelist, outtablefile='compiledVPinputs.dat') ### Make the model! fitpars, fiterrors, parinfo, linecmts = stevebvpfit.readpars( 'compiledVPinputs.dat') # read this back in to load params cfg.fitidx = stevebvpfit.fitpix( wave, fitpars) # set the pixels in the line regions model = stevebvpfit.voigtfunc( wave, fitpars) # generate the Voigt profiles of all lines ### Instantiate XSpectrum1D object and write it out outspec = XSpectrum1D.from_tuple((wave, model, normsig)) outspec.write_to_fits(outfile)
def spec_from_array(wave,flux,sig,**kwargs): """ return spectrum from arrays of wave, flux and sigma """ ituple = (wave, flux, sig) spectrum = XSpectrum1D.from_tuple(ituple, **kwargs) # Polish a bit -- Deal with NAN, inf, and *very* large values that will exceed # the floating point precision of float32 for var which is sig**2 (i.e. 1e38) bad_flux = np.any([np.isnan(spectrum.flux), np.isinf(spectrum.flux), np.abs(spectrum.flux) > 1e30, spectrum.sig ** 2 > 1e10, ], axis=0) if np.sum(bad_flux): msgs.warn("There are some bad flux values in this spectrum. Will zero them out and mask them (not ideal)") spectrum.data['flux'][spectrum.select][bad_flux] = 0. spectrum.data['sig'][spectrum.select][bad_flux] = 0. return spectrum
def compare_boxcar(pp,lrdx_sciobj,pypit_boxfile, iso): '''Compare boxcar extractions ''' # Read/Load pypit_boxspec = lsio.readspec(pypit_boxfile) # Read LowRedux sig = np.sqrt(lrdx_sciobj['MASK_BOX']/(lrdx_sciobj['SIVAR_BOX'] + (lrdx_sciobj['MASK_BOX']==0))) lwrdx_boxspec = XSpectrum1D.from_tuple( (lrdx_sciobj['WAVE_BOX'], lrdx_sciobj['FLUX_BOX'], sig) ) # Plot plt.clf() fig = plt.figure(figsize=(16,11)) gs = gridspec.GridSpec(2, 1) fig.suptitle("Instr={:s}, Setup={:s} :: Boxcar Extractions for {:s} :: PYPIT ({:s})".format(iso[0], iso[1], iso[2], pypit.version), fontsize=18.) for qq in range(2): ax = plt.subplot(gs[qq]) if qq == 0: xlim = None else: xlim = (6700,7000) ymax = np.median(pypit_boxspec.flux)*2. # PYPIT ax.plot(pypit_boxspec.dispersion, pypit_boxspec.flux, 'k-', drawstyle='steps',label='PYPIT') ax.plot(pypit_boxspec.dispersion, pypit_boxspec.sig, 'g-', drawstyle='steps') # LowRedux ax.plot(lwrdx_boxspec.dispersion, lwrdx_boxspec.flux, '-', color='blue',label='LowRedux') ax.plot(lwrdx_boxspec.dispersion, lwrdx_boxspec.sig, '-', color='gray') # Axes if xlim is None: ax.set_xlim(np.min(pypit_boxspec.dispersion.value), np.max(pypit_boxspec.dispersion.value)) else: ax.set_xlim(xlim) ax.set_ylim(0.,ymax) ax.set_xlabel('Wavelength',fontsize=19.) ax.set_ylabel('electrons',fontsize=19.) # Legend legend = plt.legend(loc='upper right', borderpad=0.3, handletextpad=0.3, fontsize='x-large') # Finish plt.tight_layout(pad=0.2,h_pad=0.,w_pad=0.1,rect=[0, 0.03, 1, 0.95]) pp.savefig(bbox_inches='tight') plt.close()
def plot_vel(ax, spec, iline, z, dvlims, complist=None, fwhm=3, min_ew_blends=0.01*u.AA): # first normalize if not spec.normed: spec.normalize(co=spec.co) # first identify good components good_comps = [] good_comps_aux = ltiu.get_components_at_z(complist, z, dvlims) for comp in good_comps_aux: for aline in comp._abslines: if aline.name == iline['name']: good_comps += [comp] break # bad comps will be those unrelated to the given redshift/transition bad_comps = [] for comp in complist: if comp not in good_comps: bad_comps += [comp] # only good comps will have a model if len(good_comps) > 0: # import pdb; pdb.set_trace() model_spec = lav.voigt_from_components(spec.wavelength, good_comps, fwhm=fwhm) else: model_spec = XSpectrum1D.from_tuple((spec.wavelength, np.ones(spec.npix))) # main plot velo = ltu.dv_from_z(spec.wavelength/iline['wrest'] - 1. , z) ax.plot(velo, spec.flux, drawstyle='steps-mid', color=COLOR_FLUX) plot_spec_complist(ax, velo, spec, bad_comps, min_ew = min_ew_blends, color=COLOR_BLEND, lw=2, drawstyle='steps-mid') plot_spec_complist(ax, velo, model_spec, good_comps, min_ew = None, color=COLOR_MODEL, lw=1, ls='-') if spec.sig_is_set: ax.plot(velo, spec.sig, drawstyle='steps-mid', color=COLOR_SIG, lw=0.5) # Zero velocity line ax.plot([0., 0.], [-1e9, 1e9], ':', color='gray') # Unity flux level line ax.plot([-1e9, 1e9], [1, 1], ':', color='b', lw=0.5) # Zero flux level line ax.plot([-1e9, 1e9], [0, 0], '--', color='k', lw=1)
def compose_model(spec,filelist,outfile): ''' Generates full-model spectrum (XSpectrum1D) from a set of joebvp output files and writes out a file with the spectrum. Parameters ---------- spec : string or XSpectrum1D The spectrum to be fitted with the input lines filelist : list of strings or str This should be a list containing the names of VP input files or a string referring to a file simply listing the input files. See joebvpfit.readpars for details of file format outfile : str Name of model spectrum output file ''' ### Deal with alternate input types if isinstance(spec,str): specobj = readspec(spec) else: specobj = spec ### Load essentials from spectrum wave = specobj.wavelength.value normsig=specobj.sig.value/specobj.co.value cfg.wave = wave ### Concatenate all the parameter tables concatenate_line_tables(filelist,outtablefile='compiledVPinputs.dat') ### Make the model! fitpars, fiterrors, parinfo, linecmts = joebvpfit.readpars('compiledVPinputs.dat') # read this back in to load params cfg.fitidx = joebvpfit.fitpix(wave, fitpars) # set the pixels in the line regions model = joebvpfit.voigtfunc(wave,fitpars) # generate the Voigt profiles of all lines ### Instantiate XSpectrum1D object and write it out outspec=XSpectrum1D.from_tuple((wave,model,normsig)) outspec.write_to_fits(outfile)
def test_local_median(): fl = np.ones(100) wv = np.linspace(1000,2000, 100) er = np.ones(100)*0.1 spec = XSpectrum1D.from_tuple((wv, fl, er)) lm = ltaip.local_median(spec.wavelength, spec.flux, spec.sig, 1300*u.AA, npix=15) np.testing.assert_allclose(lm, 1.) # out of ranges lm = ltaip.local_median(spec.wavelength, spec.flux, spec.sig, 5300*u.AA, npix=15, default=None) assert lm is None # bad values sig_aux = np.array(spec.sig) sig_aux[90:100] = 0. spec.sig = sig_aux lm = ltaip.local_median(spec.wavelength, spec.flux, spec.sig, 1950*u.AA, npix=2, default=None) assert lm is None # with real noise now rstate = RandomState(3) spec2 = spec.add_noise(s2n=spec.flux/spec.sig, rstate=rstate) lm = ltaip.local_median(spec2.wavelength, spec2.flux, spec2.sig, 1300*u.AA, npix=15) np.testing.assert_allclose(lm, 0.9428995251655579)
def parse_UVES_popler(hdulist): """ Read a spectrum from a UVES_popler-style fits file. Parameters ---------- hdulist : FITS HDU list Returns ------- xspec1d : XSpectrum1D Parsed spectrum """ from linetools.spectra.xspectrum1d import XSpectrum1D hd = hdulist[0].header uwave = setwave(hd) * u.Angstrom co = hdulist[0].data[3] fx = hdulist[0].data[0] * co # Flux sig = hdulist[0].data[1] * co xspec1d = XSpectrum1D.from_tuple((uwave, fx, sig, co)) return xspec1d
def parse_linetools_spectrum_format(hdulist, **kwargs): """ Parse an old linetools-format spectrum from an hdulist Parameters ---------- hdulist : FITS HDU list Returns ------- xspec1d : XSpectrum1D Parsed spectrum """ if 'WAVELENGTH' not in hdulist: pdb.set_trace() xspec1d = XSpectrum1D.from_spec1d(spec1d) else: wave = hdulist['WAVELENGTH'].data * u.AA fx = hdulist['FLUX'].data # Error array if 'ERROR' in hdulist: sig = hdulist['ERROR'].data else: sig = None if 'CONTINUUM' in hdulist: co = hdulist['CONTINUUM'].data else: co = None xspec1d = XSpectrum1D.from_tuple((wave, fx, sig, co), **kwargs) if 'METADATA' in hdulist[0].header: # Prepare for JSON (bug fix of sorts) metas = hdulist[0].header['METADATA'] ipos = metas.rfind('}') xspec1d.meta.update(json.loads(metas[:ipos+1])) return xspec1d
def init_LLS(self, fit_file, spec): import json # Read the JSON file with open(fit_file) as data_file: lls_dict = json.load(data_file) # Init continuum try: self.conti_dict = lls_dict["conti_model"] except KeyError: # Historic self.conti_dict = lls_dict["conti"] else: try: self.base_continuum = Quantity(lls_dict["conti"]) except: print("Will generate a new base continuum") self.base_continuum = None else: self.continuum = XSpectrum1D.from_tuple((spec.wavelength, np.ones(len(spec.wavelength)))) # self.update_conti() # Check spectra names if spec.filename != lls_dict["spec_file"]: warnings.warn("Spec file names do not match!") # LLS for key in lls_dict["LLS"].keys(): # QtCore.pyqtRemoveInputHook() # xdb.set_trace() # QtCore.pyqtRestoreInputHook() self.add_LLS( lls_dict["LLS"][key]["z"], NHI=lls_dict["LLS"][key]["NHI"], bval=lls_dict["LLS"][key]["bval"] * u.km / u.s, comment=lls_dict["LLS"][key]["comment"], model=False, ) self.smooth = lls_dict["smooth"] try: self.zqso = lls_dict["zqso"] except KeyError: self.zqso = None