def rebin_spec(spec, wavnew, waveunits='um'): from pysynphot import spectrum, observation # Gives same error answer: Err = np.array([np.sqrt(sum(spec[2].value[idx_include(wavnew,[((wavnew[0] if n==0 else # wavnew[n-1]+wavnew[n])/2,wavnew[-1] if n==len(wavnew) else (wavnew[n]+wavnew[n+1])/2)])]**2)) for n in range( # len(wavnew)-1)])*spec[2].unit if spec[2] is not '' else '' if len(spec) == 2: spec += [''] try: Flx, Err, filt = spectrum.ArraySourceSpectrum( wave=spec[0].value, flux=spec[1].value), spectrum.ArraySourceSpectrum( wave=spec[0].value, flux=spec[2].value ) if spec[2] else '', spectrum.ArraySpectralElement( spec[0].value, np.ones(len(spec[0])), waveunits=waveunits) except: spec, wavnew = [i * q.Unit('') for i in spec], wavnew * q.Unit('') Flx, Err, filt = spectrum.ArraySourceSpectrum( wave=spec[0].value, flux=spec[1].value), spectrum.ArraySourceSpectrum( wave=spec[0].value, flux=spec[2].value ) if spec[2] else '', spectrum.ArraySpectralElement( spec[0].value, np.ones(len(spec[0])), waveunits=waveunits) return [ wavnew, observation.Observation(Flx, filt, binset=wavnew.value, force='taper').binflux * spec[1].unit, observation.Observation(Err, filt, binset=wavnew.value, force='taper').binflux * spec[2].unit if spec[2] else np.ones(len(wavnew)) * spec[1].unit ]
def rebin_spec(wave, specin, wavnew): spec = spectrum.ArraySourceSpectrum(wave=wave, flux=specin) f = np.ones(len(wave)) filt = spectrum.ArraySpectralElement(wave, f, waveunits='angstrom') obs = observation.Observation(spec, filt, binset=wavnew, force='taper') return obs.binflux
def spec_res_downgrade(l_in, spec_in, l_out): templ_spec = spectrum.ArraySourceSpectrum(wave=l_in, flux=spec_in) white_filter = spectrum.ArraySpectralElement(l_out,\ np.ones(len(l_out)), waveunits='angstrom') convolved_spec = observation.Observation(templ_spec,\ white_filter, binset=l_out, force='taper').binflux return convolved_spec
def spectra_rebin(wave,flux,rebin_wave): spect=spectrum.ArraySourceSpectrum(wave=wave.values,flux=flux.values) f = np.ones(len(wave)) filt=spectrum.ArraySpectralElement(wave.values,f,waveunits='microns') obs=observation.Observation(spect,filt,binset=rebin_wave,force='taper') return obs.binflux
def rebin(new_wav, old_wav, flux): f_ = np.ones(len(old_wav)) spec_ = pysynspec.ArraySourceSpectrum(wave=old_wav, flux=flux) filt = pysynspec.ArraySpectralElement(old_wav, f_, waveunits='angstrom') obs = observation.Observation(spec_, filt, binset=new_wav, force='taper') newflux = obs.binflux return newflux
def test_sample_units(): defwave = np.linspace(0.1, 1, 10) defthru = defwave s = spec.ArraySpectralElement(defwave, defthru, 'm', 'TestArray') angwave = defwave * 1.e10 np.testing.assert_allclose(s(angwave), s.sample(defwave))
def rebin_spec(wave, specin, wavnew): '''(inwave (ndarray),influx (ndarray),outwave(ndarray)-> outflux Correctly rebins spectra ''' spec = spectrum.ArraySourceSpectrum(wave=wave, flux=specin) f = nu.ones(len(wave)) filt = spectrum.ArraySpectralElement(wave, f, waveunits='angstrom') obs = observation.Observation(spec, filt, binset=wavnew, force='taper') return obs.binflux
def rebin_spec(wavelength, flux, waveout, keepneg=False): spec = spectrum.ArraySourceSpectrum(wave=wavelength, flux=flux, keepneg=keepneg) f = np.ones(len(flux)) filt = spectrum.ArraySpectralElement(wavelength.to(wavelength.unit).value, f, waveunits=str(wavelength.unit)) obs = observation.Observation(spec, filt, binset=waveout, force='taper') return obs.binflux
def rebin_spec(wave, specin, wavnew): ''' Given wavelength, a spectrum, and new wavelength array, this function resamples the spectrum to match new array. ''' import numpy as np from pysynphot import observation from pysynphot import spectrum spec = spectrum.ArraySourceSpectrum(wave=wave, flux=specin, keepneg=True) f = np.ones(len(wave)) filt = spectrum.ArraySpectralElement(wave, f, waveunits='angstrom') obs = observation.Observation(spec, filt, binset=wavnew, force='taper') return obs.binflux
def rebin_spec(wave, specin, wavnew): """ Rebin spectra to bins used in wavnew. Ref: http://www.astrobetter.com/blog/2013/08/12/python-tip-re-sampling-spectra-with-pysynphot/ """ from pysynphot import observation from pysynphot import spectrum as pysynphot_spec import numpy as np spec = pysynphot_spec.ArraySourceSpectrum(wave=wave, flux=specin) f = np.ones(len(wave)) filt = pysynphot_spec.ArraySpectralElement(wave, f, waveunits='angstrom') obs = observation.Observation(spec, filt, binset=wavnew, force='taper') return obs.binflux
def get_ukirt_filter(filt_name): path_to_file = inspect.getsourcefile(Vega) directory = os.path.split(path_to_file)[0] + '/' filt_file = 'ukirt_' filt_file += filt_name.lower() filt_file += '.fits' t = Table.read(directory + filt_file) # Convert to photlam flux units (m->cm and nm->Ang). # Drop the arcsec density... but sill there spec = spectrum.ArraySpectralElement(wave=t['col1'], throughput=t['col2'], waveunits='Angstrom', name='UKIRT_'+filt_name) return spec
def read_mk_sky_transmission(pwv=1.6, airmass=1.5): path_to_file = inspect.getsourcefile(Vega) directory = os.path.split(path_to_file)[0] + '/maunakea_files/' pwv_suffix = {1.0: '10', 1.6: '16', 3.0: '30', 5.0: '50'} am_suffix = {1.0: '10', 1.5: '15', 2.0: '20'} if pwv not in pwv_suffix.keys(): print 'Invalid precipatable water vapor (PWV): ', pwv print 'Choose from:' print pwv_suffix.keys() return if airmass not in am_suffix.keys(): print 'Invalid airmass (AM): ', airmass print 'Choose from:' print am_suffix.keys() return mk_sky_file = 'mktrans_zm_' mk_sky_file += pwv_suffix[pwv] + '_' mk_sky_file += am_suffix[airmass] + '.dat' try: t = Table.read(directory + mk_sky_file + '.fits') except IOError: t = Table.read(directory + mk_sky_file, format='ascii') t.rename_column('col1', 'wave') # Units in microns t.rename_column('col2', 'trans') # Units in percent transmitted t['wave'].unit = 'micron' t.write(directory + mk_sky_file + '.fits') spec = spectrum.ArraySpectralElement(wave=t['wave'], throughput=t['trans'], waveunits='micron', name='Maunakea Trans') spec.convert(units.Angstrom) return spec
def rebin_spec(wave, specin, wavnew): # wavnew is the new wave grid spec = spectrum.ArraySourceSpectrum(wave=wave, flux=specin) # configures wave/spectrum for pysynphot f = np.ones(len(wave)) # preserve all flux at all wavelengths (no throughput curve) filt = spectrum.ArraySpectralElement(wave, f, waveunits='angstrom') # apply throughput curve 'filter' (not necessary for us?) obs = observation.Observation(spec, filt, binset=wavnew, force='taper') return obs.binflux
def ssp_rebin(logL_ssp, spec_ssp, dlogL_new, Lll=3250.): ''' rebin a GRID of model spectrum to have an identical velocity resolution to an input spectrum intended to be used on a grid of models with wavelength varying along final axis (in 3d array) DEPENDS ON pysynphot, which may not be an awesome thing, but it definitely preserves spectral integrity, and does not suffer from drawbacks of interpolation (failing to average line profiles) ''' dlogL_ssp = np.median(logL_ssp[1:] - logL_ssp[:-1]) f = dlogL_ssp / dlogL_new # print 'zoom factor: {}'.format(f) # print 'new array should have length {}'.format(logL_ssp.shape[0]*f) # print spec_ssp.shape # we want to only sample where we're sure we have data CRVAL1_new = logL_ssp[0] - 0.5 * dlogL_ssp + 0.5 * dlogL_new CRSTOP_new = logL_ssp[-1] + 0.5 * dlogL_ssp - 0.5 * dlogL_new NAXIS1_new = int((CRSTOP_new - CRVAL1_new) / dlogL_new) # start at exp(CRVAL1_new) AA, and take samples every exp(dlogL_new) AA logL_ssp_new = CRVAL1_new + \ np.linspace(0., dlogL_new*(NAXIS1_new - 1), NAXIS1_new) L_new = np.exp(logL_ssp_new) L_ssp = np.exp(logL_ssp) # now find the desired new wavelengths spec = spectrum.ArraySourceSpectrum(wave=L_ssp, flux=spec_ssp) f = np.ones_like(L_ssp) filt = spectrum.ArraySpectralElement(wave=L_ssp, throughput=f, waveunits='angstrom') obs = observation.Observation(spec, filt, binset=L_new, force='taper') spec_ssp_new = obs.binflux # the following are previous attempts to do this rebinning ''' # first, interpolate to a constant multiple of the desired resolution r_interm = int(1./f) print r_interm dlogL_interm = f * dlogL_new print dlogL_interm CDELT1_interm = dlogL_interm CRVAL1_interm = logL_ssp[0] + 0.5*CDELT1_interm CRSTOP_interm = logL_ssp[-1] - 0.5*CDELT1_interm NAXIS1_interm = int((CRSTOP_interm - CRVAL1_interm) / CDELT1_interm) logL_ssp_interm = CRVAL1_interm + np.linspace( 0., CDELT1_interm * (NAXIS1_interm - 1), NAXIS1_interm) edges_interm = np.column_stack((logL_ssp_interm - 0.5*CDELT1_interm, logL_ssp_interm + 0.5*CDELT1_interm)) spec_interp = interp1d(logL_ssp, spec_ssp) spec_interm = spec_interp(logL_ssp_interm) print spec_interm.shape spec_ssp_new = zoom(spec_interm, zoom=[1., 1., 1./r_interm])[1:-1] logL_ssp_new = zoom(logL_ssp_interm, zoom=1./r_interm)[1:-1] print logL_ssp_new.shape''' '''s = np.cumsum(spec_ssp, axis=-1) # interpolate cumulative array s_interpolator = interp1d(x=logL_ssp, y=s, kind='linear') s_interpolated_l = s_interpolator(edges[:, 0]) s_interpolated_u = s_interpolator(edges[:, 1]) total_in_bin = np.diff( np.row_stack((s_interpolated_l, s_interpolated_u)), n=1, axis=0) spec_ssp_new = total_in_bin * (dlogL_new/dlogL_ssp)''' return spec_ssp_new, logL_ssp_new
def test_binning_methods(): """ Compare the pysynphot binflux.sum() routine on filter integrations at different resolutions. Shows bug in routine: integrated flux depends on the filter resolution! Fix: manually integrate the binned filter function. Shows that this method performs much better, getting nearly the same output flux for different filter resolutions, as we would expect """ # We'll test an integration of the vega spectrum through the WFC3-IR F127M filter vega = synthetic.Vega() filt = pysynphot.ObsBandpass('wfc3,ir,f127m') # Convert to ArraySpectralElement for resampling. filt = spectrum.ArraySpectralElement(filt.wave, filt.throughput, waveunits=filt.waveunits) # Two rebinning schemes: one coarse and the other fine idx = np.where(filt.throughput > 0.001)[0] new_wave = np.linspace(filt.wave[idx[0]], filt.wave[idx[-1]], 1500, dtype=float) filt_fine = filt.resample(new_wave) wave_bin = vega.wave filt_bin = synthetic.rebin_spec(filt.wave, filt.throughput, wave_bin) filt_coarse = pysynphot.ArrayBandpass(wave_bin, filt_bin) # Do the filter integration in 2 methods: one with pysynphot binflux, # the other with manual integration vega_obs_fine = obs.Observation(vega, filt_fine, binset=filt_fine.wave, force='taper') vega_obs_coarse = obs.Observation(vega, filt_coarse, binset=filt_coarse.wave, force='taper') fine_binflux = vega_obs_fine.binflux.sum() coarse_binflux = vega_obs_coarse.binflux.sum() diff_f = np.diff(vega_obs_fine.binwave) diff_f = np.append(diff_f, diff_f[-1]) fine_manual = np.sum(vega_obs_fine.binflux * diff_f) diff_c = np.diff(vega_obs_coarse.binwave) diff_c = np.append(diff_c, diff_c[-1]) coarse_manual = np.sum(vega_obs_coarse.binflux * diff_c) print('**************************************') print('Integrated flux with binflux:') print('fine binning: {0}'.format(fine_binflux)) print('coarse binning: {0}'.format(coarse_binflux)) print('And with manual integration:') print('fine binning: {0}'.format(fine_manual)) print('coarse binning: {0}'.format(coarse_manual)) print('**************************************') pdb.set_trace() return