def sanity_checkExample(self): """ Doppler shift -- Checking whether example works """ from PyAstronomy import pyasl import matplotlib.pylab as plt import numpy as np # Create a "spectrum" with 0.01 A binning ... wvl = np.linspace(6000., 6100., 10000) # ... a gradiant in the continuum ... flux = np.ones(len(wvl)) + (wvl/wvl.min())*0.05 # ... and a Gaussian absoption line flux -= np.exp( -(wvl-6050.)**2/(2.*0.5**2) )*0.05 # Shift that spectrum redward by 20 km/s using # "firstlast" as edge handling method. nflux1, wlprime1 = pyasl.dopplerShift(wvl, flux, 20., edgeHandling="firstlast") # Shift the red-shifted spectrum blueward by 20 km/s, i.e., # back on the initial spectrum. nflux2, wlprime = pyasl.dopplerShift(wvl, nflux1, -20., \ edgeHandling="fillValue", fillValue=1.0) # Check the maximum difference in the central part indi = np.arange(len(flux)-200) + 100 print "Maximal difference (without outer 100 bins): ", \ max(np.abs(flux[indi]-nflux2[indi])) # Plot the outcome plt.title("Initial (blue), shifted (red), and back-shifted (green) spectrum") plt.plot(wvl, flux, 'b.-') plt.plot(wvl, nflux1, 'r.-') plt.plot(wvl, nflux2, 'g.-')
def doppler_shift(wlen, flux, RV): flux_temp, wlen_prime = dopplerShift(wlen, flux, RV, edgeHandling='firstlast') wlen_temp, flux_temp = np.transpose( [[wlen[i], flux_temp[i]] for i in range(len(wlen)) if (wlen[i] >= wlen_prime[0] and wlen[i] <= wlen_prime[-1])]) return wlen_temp, flux_temp
#thisfit.perror for f in range(len(filenames)): hdu_list = fits.open(filenames[f]) mwav, mflx = hdu_list[0].data[0], hdu_list[0].data[1] #print(len(hdu_list)) plt.xlabel('Wavelength (microns)') plt.ylabel('Norm. Flux') plt.plot(ReducedWavelength, ReducedNormFlux, 'b', linewidth=0.8) ##We now know the model goes from 2.203-2.226um, plt.plot(mwav / 10000, mflx / np.median(mflx) * np.median(ReducedNormFlux), 'g') nflux1, wlprime1 = pyasl.dopplerShift(mwav / 10000, mflx / np.median(mflx) * np.median(ReducedNormFlux), 70., edgeHandling="fillValue", fillValue=np.median(NormFlux)) #nflux1, wlprime1 = pyasl.dopplerShift(ReducedWavelength, ReducedNormFlux, 30., edgeHandling="fillValue", fillValue=np.median(NormFlux)) #nflux2, wlprime = pyasl.dopplerShift(ReducedWavelength, nflux1, -30., \ #edgeHandling="fillValue", fillValue=np.median(NormFlux)) nflux2, wlprime = pyasl.dopplerShift(mwav, nflux1, -60., \ edgeHandling="fillValue", fillValue=np.median(NormFlux)) indi = np.arange(len(mflx) - 200) + 100 #indi = np.arange(len(ReducedNormFlux)-200) + 100 print("Maximal difference (without outer 100 bins): ", \ #max(np.abs(ReducedNormFlux[indi]-nflux2[indi]))) max(np.abs(mflx[indi]-nflux2[indi]))) #x = np.arange(len(dwav))
for i in range(nbins): if ((i+1)%10) == 0: foc.seek(foc.tell()+1) flux_oc[i] = foc.read(8) foc.seek(foc.tell()+1) # if wav0 == 6653: # if wav0 == 4688: # cont_wavs = (4700, 4720) cont_wavs = (6665, 6688) nflux_spe1, nwav_spe1 = pyasl.dopplerShift(wav_spe, flux_spe1, vr1_C[m], edgeHandling="firstlast") nflux_spe2, nwav_spe2 = pyasl.dopplerShift(wav_spe, flux_spe2, vr2_C[m], edgeHandling="firstlast") cont1 = normalize_line_linear(wav_spe, nflux_spe1, cont_wavs[0], cont_wavs[1]) cont2 = normalize_line_linear(wav_spe, nflux_spe2, cont_wavs[0], cont_wavs[1]) nflux_spe1_1 = nflux_spe1 / cont1(wav_spe) nflux_spe2_1 = nflux_spe2 / cont2(wav_spe) nflux_spe1, nwav_spe1 = pyasl.dopplerShift(wav_spe, flux_spe1, vr1[m], edgeHandling="firstlast") nflux_spe2, nwav_spe2 = pyasl.dopplerShift(wav_spe, flux_spe2, vr2[m], edgeHandling="firstlast") cont1 = normalize_line_linear(wav_spe, nflux_spe1, cont_wavs[0], cont_wavs[1]) cont2 = normalize_line_linear(wav_spe, nflux_spe2, cont_wavs[0], cont_wavs[1]) nflux_spe1_2 = nflux_spe1 / cont1(wav_spe) nflux_spe2_2 = nflux_spe2 / cont2(wav_spe)
def barycorr_crires(wavelength, flux, header, extra_offset=None): """Calculate Heliocentric correction values and apply to spectrum. # SHOULD test again with bary and see what the difference is. """ if header is None: logging.warning( "No header information to calculate heliocentric correction.") header = {} if (extra_offset is None) or (extra_offset == 0): return wavelength, flux try: longitude = float(header["HIERARCH ESO TEL GEOLON"]) latitude = float(header["HIERARCH ESO TEL GEOLAT"]) altitude = float(header["HIERARCH ESO TEL GEOELEV"]) ra = header["RA"] # CRIRES RA already in degrees dec = header["DEC"] # CRIRES hdr DEC already in degrees time = header["DATE-OBS"] # Observing date '2012-08-02T08:47:30.8425' # Convert easily to julian date with ephem jd = ephem.julian_date(time.replace("T", " ").split(".")[0]) # Calculate Heliocentric velocity helcorr = pyasl.helcorr(longitude, latitude, altitude, ra, dec, jd, debug=False) helcorr = helcorr[0] if header.get("BARYDONE", False): warnings.warn( "Applying barycentric correction when 'BARYDONE' already flag set." ) except KeyError as e: logging.warning("Not a valid header so can't do automatic correction.") helcorr = 0.0 if extra_offset is not None: logging.warning( "Warning!!!! have included a manual offset for testing") else: extra_offset = 0.0 helcorr_val = helcorr + extra_offset if helcorr_val == 0: logging.warning("Helcorr value was zero") return wavelength, flux else: # Apply Doppler shift to the target spectra with helcorr correction velocity nflux, wlprime = pyasl.dopplerShift(wavelength, flux, helcorr_val, edgeHandling=None, fillValue=None) logging.info( __("RV Size of Heliocenter correction for spectra {}", helcorr_val)) return wlprime, nflux
"flux": flux_P }, } wav_band = [759 * 1e-7, 772 * 1e-7] # In cm R = 3e5 # Put spectra all on the same wavelength grid _, data["S"]["flux_resampled"] = utils.resample(wav_S, wav_band, R, flux_S) _, data["T"]["flux_resampled"] = utils.resample(wav_T, wav_band, R, flux_T) data["wav_resampled"], data["P"]["flux_resampled"] = utils.resample( wav_P, wav_band, R, flux_P) # Doppler shift S and P to simulate v_star data["S"]["flux_resampled_shifted"], _ = pyasl.dopplerShift( data["wav_resampled"], data["S"]["flux_resampled"], 20.0, edgeHandling="firstlast", ) data["P"]["flux_resampled_shifted"], _ = pyasl.dopplerShift( data["wav_resampled"], data["P"]["flux_resampled"], 20.0, edgeHandling="firstlast", ) ############################### # Run CCF for different sigma_w ############################### # Unloaded dict for trying numbda. TODO: put back wav = data["wav_resampled"] S = data["S"]["flux_resampled_shifted"]
#wave_log = np.min(Wavelength2)*np.exp(np.log(np.max(Wavelength2)/np.min(Wavelength2))/40*np.arange(wave_log)) #drv = np.log(wave_log[1]/wave_log[0])*2.998e5 #plt.plot (wave_log, NormFlux2, 'b') # Create a "spectrum" with 0.01 A binning ... #wvl = np.linspace(6000., 6100., 10000) # ... a gradient in the continuum ... #flux = np.ones(len(Wavelength)) + (Wavelength/Wavelength.min())*0.05 # ... and a Gaussian absoption line #flux -= np.exp( -(Wavelength-6050.)**2/(2.*0.5**2) )*0.05 # Shift that spectrum redward by 30 km/s using # "firstlast" as edge handling method. nflux1, wlprime1 = pyasl.dopplerShift(Wavelength, NormFlux, 30., edgeHandling="fillValue", fillValue=np.median(NormFlux)) # Shift the red-shifted spectrum blueward by 30 km/s, i.e., # back on the initial spectrum. nflux2, wlprime = pyasl.dopplerShift(Wavelength, nflux1, -30., \ edgeHandling="fillValue", fillValue=np.median(NormFlux)) # Check the maximum difference in the central part indi = np.arange(len(NormFlux) - 200) + 100 print("Maximal difference (without outer 100 bins): ", \ max(np.abs(NormFlux[indi]-nflux2[indi]))) # Plot the outcome plt.title("Initial (blue), shifted (red), and back-shifted (green) spectrum")
def read_observations(fname, start_synth, end_synth): """Read observed spectrum of different types and return wavelength and flux. Input ----- fname : filename of the spectrum. Currently only fits and text files accepted. start_synth : starting wavelength where the observed spectrum is cut end_synth : ending wavelength where the observed spectrum is cut Output ----- wavelength_obs : observed wavelength flux_obs : observed flux """ # These are the approved formats extension = ('.dat', '.txt', '.spec', '.fits', '.csv') if fname.endswith(extension): if (fname[-4:] == '.dat') or (fname[-4:] == '.txt'): with open(fname, 'r') as f: lines = (line for line in f if not line[0].isalpha()) # skip header wave, flux = np.loadtxt(lines, unpack=True, usecols=(0, 1)) elif fname[-4:] == '.csv': with open(fname, 'r') as f: lines = (line for line in f if not line[0].isalpha()) # skip header w, f = np.loadtxt(lines, delimiter=',', unpack=True, usecols=(0, 1)) flux, wave = pyasl.dopplerShift(w, f, -0.36, edgeHandling="firstlast") #wave = (100000000/(wave)) #wl = wave[::-1] #wave = wl / (1.0 + (5.792105E-2/(238.0185E0 - (1.E4/wl)**2)) + (1.67917E-3/(57.362E0 - (1.E4/wl)**2))) elif fname[-5:] == '.fits': hdulist = fits.open(fname) header = hdulist[0].header # Only 1-D spectrum accepted. flux = hdulist[0].data # flux data in the primary flux = np.array(flux, dtype=np.float64) start_wave = header['CRVAL1'] # initial wavelenght # step = header['CD1_1'] #step in wavelenght step = header['CDELT1'] # increment per pixel w0, dw, n = start_wave, step, len(flux) w = start_wave + step * n wave = np.linspace(w0, w, n, endpoint=False) # These types are produced by MOOGme (fits format). elif fname[-5:] == '.spec': hdulist = fits.open(fname) x = hdulist[1].data flux = x['flux'] flux = np.array(flux) flux = flux.astype(np.float) # flux data in the primary wave = x['wavelength'] wave = np.array(wave) wave = wave.astype(np.float) #flux, wave = pyasl.dopplerShift(w, f, -0.15, edgeHandling="firstlast") # Cut observations to the intervals of the synthesis delta_l = wave[1] - wave[0] wavelength_obs = wave[np.where((wave >= float(start_synth)) & (wave <= float(end_synth)))] flux_obs = flux[np.where((wave >= float(start_synth)) & (wave <= float(end_synth)))] return wavelength_obs, flux_obs, delta_l else: print( 'Spectrum is not in acceptable format. Convert to ascii of fits.') wavelength_obs, flux_obs, delta_l = (None, None, None) return wavelength_obs, flux_obs, delta_l