def autosmooth(x_array, y_array, var_y=None): if var_y is not None: error = np.sqrt(var_y) new_y_init = df.gsmooth(x_array, y_array, var_y, .001) SNR = np.mean(y_array / error) # SNR = np.mean(new_y_init / error) else: var_y = np.ones(len(x_array)) new_y_init = df.gsmooth(x_array, y_array, var_y, .002) error = np.absolute(y_array - new_y_init) sm_error = df.gsmooth(x_array, error, var_y, .008) SNR = np.median(new_y_init / sm_error) if SNR < 5: vexp_auto = .0045 #temp value, need to fine tune using SNR in excel spreadsheet elif 5 <= SNR < 20: vexp_auto = .004 elif 20 <= SNR < 40: vexp_auto = .003 elif 40 <= SNR < 60: vexp_auto = .002 elif 60 <= SNR < 100: vexp_auto = .0015 else: vexp_auto = .001 return vexp_auto, SNR
def find_vexp(x_array, y_array, var_y=None): if var_y is not None: error = np.sqrt(var_y) new_y_init = df.gsmooth(x_array, y_array, var_y, .002) SNR = np.median(new_y_init / error) else: new_y_init = df.gsmooth(x_array, y_array, var_y, .002) #this smoothing should get in right ballpark error = np.absolute(y_array - new_y_init) sm_error = df.gsmooth(x_array, error, var_y, .008) SNR = np.median(new_y_init / sm_error) #TODO: interpolate a function of SNR # vexp_line = np.polyfit([2.5, 80], [.0045, .001], 1) # coeff_0 = vexp_line[0] # coeff_1 = vexp_line[1] # results from above: coeff_0 = -4.51612903e-05 coeff_1 = 4.61290323e-03 vexp_auto = coeff_0*SNR + coeff_1 if SNR < 2.5: vexp_auto = .0045 if SNR > 80: vexp_auto = .001 return vexp_auto, SNR
def clip(wave, flux, ivar): # Create an array of all ones var = np.ones(len(flux), float) # Create 2 smoothed fluxes, of varying vexp sflux = df.gsmooth(wave, flux, var, 0.002) # Take the difference of the two fluxes and smooth err = abs(flux - sflux) serr = df.gsmooth(wave, err, var, 0.008) # Find the wavelengths that need to be clipped (omitting 5800-6000 region) index = np.where(((err / serr > 5.5) & (wave < 5800.0)) | ((err / serr > 5.5) & (wave > 6000.0))) index_na = np.where((err / serr > 10.5) & ((wave > 5800.0) & (wave < 6000.0))) bad_wave = wave[index] bad_wave_na = wave[index_na] # Find indices for general clipping # bad = np.array([], int) bad_ranges = [] # if don't need it to be a numpy array (A.S.) for i in range(len(bad_wave)): # bad = np.append(bad, np.where(abs(wave - bad_wave[i]) < 8)) bad_ranges.append( (bad_wave[i] - 8, bad_wave[i] + 8)) # instead save each point as tuple of desired range (A.S.) for i in range(len(bad_wave_na)): # bad = np.append(bad, np.where(abs(wave - bad_wave[i]) < 8)) bad_ranges.append((bad_wave_na[i] - 8, bad_wave_na[i] + 8)) # Set ivar to 0 for those points and return # ivar[bad] = 0 # return ivar plt.plot(wave, flux) for wave_tuple in bad_ranges: # print wave_tuple clip_points = np.where((wave > wave_tuple[0]) & (wave < wave_tuple[1])) #make sure not at edge of spectrum flux[clip_points] = np.interp( wave[clip_points], [wave_tuple[0], wave_tuple[1]], [flux[clip_points[0][0] - 1], flux[clip_points[0][-1] + 1]]) #deweight data (but not to 0), somewhat arbitrary ivar[clip_points] = np.interp( wave[clip_points], [wave_tuple[0], wave_tuple[1]], [ivar[clip_points[0][0] - 1], ivar[clip_points[0][-1] + 1]]) plt.plot(wave, flux) plt.show() return wave, flux, ivar # return bad_ranges instead of setting ivar[bad] = 0 (A.S.)
def measure_weak_si_velocity(wavelength, flux, varflux=None, plot=True): if varflux == None: varflux = np.zeros(len(wavelength), float) varflux = np.zeros(len(wavelength), float) sm_flux = df.gsmooth(wavelength, flux, varflux, .001) si_range = np.where((wavelength > 5560.) & (wavelength < 5820.)) si_wave = wavelength[si_range] si_flux = sm_flux[si_range] si_min = np.amin(si_flux) si_min_index = np.where(si_flux == si_min) si_min_wave = si_wave[si_min_index][0] c = 299792. # km/s si_rest_wave = 5979. #Angstroms v = c*((si_rest_wave/si_min_wave)**2. - 1)/(1+((si_rest_wave/si_min_wave)**2.)) # if plot: # plt.plot(wavelength, flux) # plt.plot(wavelength, sm_flux) # plt.plot(si_min_wave, si_min, 'o') # plt.xlim([5000.,7000.]) # plt.ylim([0.,.6]) # plt.show() return v, si_min_wave
def measure_ca_ratio(wavelength,flux, varflux = None, wave1 = 3550., wave2=3680.): if varflux == None: varflux = np.zeros(len(wavelength), float) sm_flux = df.gsmooth(wavelength, flux, varflux, .001) # ca_range_1 = np.where((wavelength > 3550.) & (wavelength < 3680.)) ca_range_1 = np.where((wavelength > wave1) & (wavelength < wave2)) ca_range_2 = np.where((wavelength > 3890.) & (wavelength < 3970.)) ca_wave_1 = wavelength[ca_range_1] ca_wave_2 = wavelength[ca_range_2] ca_flux_1 = sm_flux[ca_range_1] ca_flux_2 = sm_flux[ca_range_2] ca_max_1 = np.amax(ca_flux_1) ca_max_2 = np.amax(ca_flux_2) ca_max_index_1 = np.where(sm_flux == ca_max_1) ca_max_index_2 = np.where(sm_flux == ca_max_2) ca_max_wave_1 = wavelength[ca_max_index_1][0] ca_max_wave_2 = wavelength[ca_max_index_2][0] print ca_max_2/ca_max_1 plt.plot(wavelength,flux) plt.plot(wavelength,sm_flux) plt.plot(wavelength[ca_max_index_1], sm_flux[ca_max_index_1], 'o', color='orange') plt.plot(wavelength[ca_max_index_2], sm_flux[ca_max_index_2], 'o', color='orange') plt.show() return ca_max_2/ca_max_1
def find_vexp_ryan(x_array, y_array, var_y=None): if var_y is not None: error = np.sqrt(var_y) new_y_init = df.gsmooth(x_array, y_array, var_y, .002) SNR = np.median(new_y_init / error) else: new_y_init = df.gsmooth(x_array, y_array, var_y, .002) #this smoothing should get in right ballpark error = np.absolute(y_array - new_y_init) sm_error = df.gsmooth(x_array, error, var_y, .008) SNR = np.median(new_y_init / sm_error) vexp = 0.000205115 + 0.00699404*(SNR + 0.642253)**(-0.446162) if SNR > 150: vexp = .001 return vexp, SNR
def measure_velocity(wavelength, flux, wave1, wave2, vexp=.001, clip=True, rest_wave=6355., varflux=None, plot=False, error=False): sm_flux = df.gsmooth(wavelength, flux, varflux, vexp) # sigclip_region = np.where((np.absolute(flux-sm_flux)> 3.*np.sqrt(varflux)))[0] old_wave = copy.deepcopy(wavelength) old_flux = copy.deepcopy(flux) # if clip: # wavelength = np.delete(wavelength, sigclip_region) # flux = np.delete(flux, sigclip_region) # varflux = np.delete(varflux, sigclip_region) # sm_flux = np.delete(sm_flux, sigclip_region) si_range = np.where((wavelength > wave1) & (wavelength < wave2)) si_wave = wavelength[si_range] if len(si_wave) == 0: return np.nan, np.nan si_flux = sm_flux[si_range] si_min = np.amin(si_flux) si_min_index = np.where(si_flux == si_min) if len(si_min_index[0]) > 0. and (wavelength[-1] > wave2): si_min_wave = si_wave[si_min_index][0] c = 299792.458 # km/s # rest_wave = 6355. #Angstroms v = c*((rest_wave/si_min_wave)**2. - 1)/(1+((rest_wave/si_min_wave)**2.)) if error: sigma = measure_verror(wavelength, flux, varflux, wave1, wave2) if plot: f, ax1 = plt.subplots(1, 1, figsize=[7,7]) zoom = (wavelength>5500) & (wavelength < 6500) # zoom_old_sig = (old_wave[sigclip_region]>5500) & (old_wave[sigclip_region] < 6500) zoom_old = (old_wave>5500) & (old_wave < 6500) norm = 1./np.amax(flux) plt.plot(old_wave[zoom_old], norm*old_flux[zoom_old], color='red') plt.plot(wavelength[zoom], norm*flux[zoom]) plt.plot(wavelength[zoom], norm*sm_flux[zoom]) plt.plot(si_min_wave, norm*si_min, 'o', color='orange') # plt.xlim([5500.,6500.]) # plt.ylim([np.median(flux[zoom])-.2,np.median(flux[zoom])+.2]) plt.show() else: v = np.nan si_min_wave = np.nan sigma = np.nan if error: return (-1.*v)/1000., si_min_wave, sigma else: return (-1.*v)/1000., si_min_wave, np.nan
def ew_stat_error(wavelength, flux, ivar, w1, w2, w3, roi, vexp=.001, num=100): sm_flux = df.gsmooth(wavelength[roi], flux[roi], 1/ivar[roi], vexp) err = np.sqrt((1./ivar[roi])) # err = np.absolute(flux[roi] - sm_flux) sig = np.median(err) ews = [] for i in range(0, num): new_flux = copy.deepcopy(sm_flux) delta_flux = np.random.normal(loc=0, scale=sig, size=len(new_flux)) new_flux = new_flux + delta_flux ew, roi_ignore = measure_EW(wavelength[roi], new_flux, w1, w2, w3, vexp=vexp, plot=False) ews.append(ew) stat_err = np.std(ews) return stat_err
def max_wave(wavelength, flux, w1, w2, w3, vexp=.001, sys_error=False): sm_flux= df.gsmooth(wavelength, flux, None, vexp) wave_domain_1 = (wavelength > w1) & (wavelength < w2) elem_flux_1 = np.argmax(sm_flux[wave_domain_1]) #find minimum value within these flux vales to locate "dip max_wave_1 = wavelength[wave_domain_1][elem_flux_1] #find the corresponding wavelength wave_domain_2 = (wavelength > w2) & (wavelength < w3) elem_flux_2 = np.argmax(sm_flux[wave_domain_2]) #find minimum value within these flux vales to locate "dip max_wave_2 = wavelength[wave_domain_2][elem_flux_2] #find the corresponding wavelength if sys_error: #change continuum locations by a random even integer (at most 100 Angstroms) max_wave_1 = max_wave_1 + random.randint(-50, 50)*2. max_wave_2 = max_wave_2 + random.randint(-50, 50)*2. return max_wave_1, max_wave_2, wave_domain_1, wave_domain_2, elem_flux_1, elem_flux_2, sm_flux
def measure_C_velocity_from_raw(wavelength,flux,z, varflux=None): # varflux = 1./SN.ivar[SN.x1:SN.x2] # plt.plot(wavelength,flux) if varflux == None: varflux = np.zeros(len(wavelength), float) wavelength = wavelength/(1.+z) sm_flux = df.gsmooth(wavelength, flux, varflux, .001) C_range = np.where((wavelength > 6200.) & (wavelength < 6320.)) C_wave = wavelength[C_range] C_flux = sm_flux[C_range] C_min = np.amin(C_flux) C_min_index = np.where(C_flux == C_min) C_min_wave = C_wave[C_min_index][0] c = 299792. # km/s C_rest_wave = 6580. #Angstroms v = c*((C_rest_wave/C_min_wave)**2. - 1)/(1+((C_rest_wave/C_min_wave)**2.)) # v = c*(si_min_wave - si_rest_wave)/si_rest_wave # plt.plot(wavelength, flux) # plt.plot(wavelength, sm_flux) # plt.plot(C_min_wave, C_min, 'o', color='orange') # plt.show() return v, C_min_wave
def measure_velocity(wavelength, flux, wave1, wave2, vexp=.001, rest_wave=6355., varflux=None, plot=False, error=False): sm_flux = df.gsmooth(wavelength, flux, varflux, vexp) si_range = np.where((wavelength > wave1) & (wavelength < wave2)) si_wave = wavelength[si_range] if len(si_wave) == 0: return np.nan, np.nan si_flux = sm_flux[si_range] si_min = np.amin(si_flux) si_min_index = np.where(si_flux == si_min) if len(si_min_index[0]) > 0. and (wavelength[-1] > wave2): si_min_wave = si_wave[si_min_index][0] c = 299792.458 # km/s # rest_wave = 6355. #Angstroms v = c*((rest_wave/si_min_wave)**2. - 1)/(1+((rest_wave/si_min_wave)**2.)) if error: sigma = measure_verror(wavelength, flux, varflux) if plot: norm = 1./np.amax(flux) plt.plot(wavelength, norm*flux) plt.plot(wavelength, norm*sm_flux) plt.plot(si_min_wave, norm*si_min, 'o', color='orange') plt.xlim([5000.,7000.]) plt.ylim([0.,.6]) plt.show() else: v = np.nan si_min_wave = np.nan if error: return (-1.*v)/1000., si_min_wave, sigma else: return (-1.*v)/1000., si_min_wave
def measure_si_velocity_from_raw(wavelength,flux,z, varflux=None): # varflux = 1./SN.ivar[SN.x1:SN.x2] # plt.plot(wavelength,flux) if varflux == None: varflux = np.zeros(len(wavelength), float) wavelength = wavelength/(1.+z) sm_flux = df.gsmooth(wavelength, flux, varflux, .001) si_range = np.where((wavelength > 5830.) & (wavelength < 6230.)) si_wave = wavelength[si_range] si_flux = sm_flux[si_range] si_min = np.amin(si_flux) si_min_index = np.where(si_flux == si_min) si_min_wave = si_wave[si_min_index][0] c = 299792.458 # km/s si_rest_wave = 6355. #Angstroms v = c*((si_rest_wave/si_min_wave)**2. - 1)/(1+((si_rest_wave/si_min_wave)**2.)) # v = c*(si_min_wave - si_rest_wave)/si_rest_wave # plt.plot(wavelength, flux) # plt.plot(wavelength, sm_flux) # plt.plot(si_min_wave, si_min, 'o', color='orange') # plt.show() return v, si_min_wave
def measure_si_ratio(wavelength,flux, varflux = None, vexp=.002, smooth=True, dm15 = None, plot=True): # if varflux == None: # varflux = np.zeros(len(wavelength), float) if smooth: sm_flux = df.gsmooth(wavelength, flux, varflux, vexp) else: sm_flux = flux maxima = find_extrema(wavelength,sm_flux) max_waves = wavelength[maxima] max_fluxes = sm_flux[maxima] si_range_1 = np.where((wavelength > 5500.) & (wavelength < 5700.)) si_range_2 = np.where((wavelength > 5700.) & (wavelength < 6000.)) si_range_3 = np.where((wavelength > 6000.) & (wavelength < 6500.)) # si_wave_1 = wavelength[si_range_1] # si_wave_2 = wavelength[si_range_2] # si_wave_3 = wavelength[si_range_3] # si_flux_1 = sm_flux[si_range_1] # si_flux_2 = sm_flux[si_range_2] # si_flux_3 = sm_flux[si_range_3] # si_max_1 = np.amax(si_flux_1) # si_max_2 = np.amax(si_flux_2) # si_max_3 = np.amax(si_flux_3) # si_max_index_1 = np.where(si_flux_1 == si_max_1) # si_max_index_2 = np.where(si_flux_2 == si_max_2) # si_max_index_3 = np.where(si_flux_3 == si_max_3) # si_max_wave_1 = si_wave_1[si_max_index_1][0] # si_max_wave_2 = si_wave_2[si_max_index_2][0] # si_max_wave_3 = si_wave_3[si_max_index_3][0] m1s = [] m2s = [] m3s = [] for m in maxima: if m in si_range_1[0]: m1s.append(m) if m in si_range_2[0]: m2s.append(m) if m in si_range_3[0]: m3s.append(m) if len(m1s) == 0 or len(m2s) == 0 or len(m3s) == 0: m1s = [] m2s = [] m3s = [] sm_flux = df.gsmooth(wavelength, flux, varflux, vexp= vexp+.001) maxima = find_extrema(wavelength,sm_flux) for m in maxima: if m in si_range_1[0]: m1s.append(m) if m in si_range_2[0]: m2s.append(m) if m in si_range_3[0]: m3s.append(m) if len(m1s) == 0 or len(m2s) == 0 or len(m3s) == 0: print "Could not find maximum in a specified range!" return np.nan f1s = sm_flux[m1s] f2s = sm_flux[m2s] f3s = sm_flux[m3s] m1 = m1s[-1] m2 = m2s[-1] m3 = m3s[np.argmax(f3s)] # m1 = m1s[0] # m2 = m2s[-1] # m3 = m3s[-1] if dm15 != None and dm15 > 1.7: m1 = m1s[0] m2 = m2s[np.argmax(f2s)] si_max_wave_1 = wavelength[m1] si_max_wave_2 = wavelength[m2] si_max_wave_3 = wavelength[m3] si_max_1 = sm_flux[m1] si_max_2 = sm_flux[m2] si_max_3 = sm_flux[m3] weak_si_trough = np.where((wavelength >= si_max_wave_1) & (wavelength < si_max_wave_2))[0] strong_si_trough = np.where((wavelength >= si_max_wave_2) & (wavelength < si_max_wave_3))[0] interp_flux = copy.copy(flux) interp_flux[weak_si_trough] = np.interp(wavelength[weak_si_trough], [si_max_wave_1, si_max_wave_2], [si_max_1, si_max_2]) interp_flux[strong_si_trough] = np.interp(wavelength[strong_si_trough], [si_max_wave_2, si_max_wave_3], [si_max_2, si_max_3]) # v_strong, si_min_wave = measure_velocity(wavelength,flux, 5900., 6300.) # v_weak, si_weak_min_wave = measure_weak_si_velocity(wavelength,flux) # si_min_index = np.where(wavelength == si_min_wave) # si_weak_min_index = np.where(wavelength == si_weak_min_wave) #find max of diffs instead of finding minimum strong_line_diffs = interp_flux[strong_si_trough] - sm_flux[strong_si_trough] weak_line_diffs = interp_flux[weak_si_trough] - sm_flux[weak_si_trough] #Line ratio with fractional depths # strong_line = (interp_flux[si_min_index] - sm_flux[si_min_index])/interp_flux[si_min_index] # weak_line = (interp_flux[si_weak_min_index] - sm_flux[si_weak_min_index])/interp_flux[si_weak_min_index] # strong_line = (interp_flux[si_min_index] - sm_flux[si_min_index]) # weak_line = (interp_flux[si_weak_min_index] - sm_flux[si_weak_min_index]) strong_line = np.amax(strong_line_diffs) weak_line = np.amax(weak_line_diffs) strong_ind = np.where(strong_line_diffs == strong_line) weak_ind = np.where(weak_line_diffs == weak_line) ratio = weak_line/strong_line # ratio = ratio[0] # if ratio > .5: if plot: plt.plot(wavelength,flux) plt.plot(wavelength,sm_flux) plt.plot(wavelength, interp_flux) plt.plot(max_waves, max_fluxes, 'o', color='cyan') plt.plot(wavelength[strong_si_trough][strong_ind], interp_flux[strong_si_trough][strong_ind], 'o', color='orange') plt.plot(wavelength[strong_si_trough][strong_ind], sm_flux[strong_si_trough][strong_ind], 'o', color='orange') plt.plot(wavelength[weak_si_trough][weak_ind], interp_flux[weak_si_trough][weak_ind], 'o', color='orange') plt.plot(wavelength[weak_si_trough][weak_ind], sm_flux[weak_si_trough][weak_ind], 'o', color='orange') plt.xlim([5000.,7000.]) plt.ylim([0.,.6]) plt.show() # plt.plot(wavelength,flux) # plt.plot(wavelength,sm_flux) # plt.plot(wavelength, interp_flux) # plt.plot(wavelength[si_min_index], interp_flux[si_min_index], 'o', color='orange') # plt.plot(wavelength[si_min_index], sm_flux[si_min_index], 'o', color='orange') # plt.plot(wavelength[si_weak_min_index], interp_flux[si_weak_min_index], 'o', color='orange') # plt.plot(wavelength[si_weak_min_index], sm_flux[si_weak_min_index], 'o', color='orange') # plt.xlim([5000.,7000.]) # plt.show() return ratio
import numpy as np import matplotlib.pyplot as plt import datafidelity as df # Import Supernova data to work with SN=np.genfromtxt('sn2002cc-20020420-ui.flm') wavelength = SN[:,0] flux = SN[:,1] try: variance = SN[:,2] except IndexError: variance = df.genvar(wavelength, flux) # Clip flux file new_flux1, clipped = df.clip(flux) # Smooth curve new_flux2 = df.gsmooth(wavelength, flux, error, vexp = 0.004) variance = df.update_variance(wavelength, new_flux1, variance) plt.plot(wavelength, new_flux2, 'b') plt.plot(wavelength, variance) plt.show()