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 test_is_local_minima_maxima(): a = np.ones(100) #adding local minima/maxima by hand ind_lmin = [14, 50, 75] # these should be in increasing order for the assert later ind_lmax = [25, 60, 90] a[ind_lmin] = 0. # local minima a[ind_lmax] = 2. # local maxima a_lmin = ltu.is_local_minima(a) a_lmax = ltu.is_local_maxima(a) assert all(np.where(a_lmin)[0] == ind_lmin) assert all(np.where(a_lmax)[0] == ind_lmax)
def is_local_maxima(a): """For a given array a, returns true for local maxima""" return ltu.is_local_maxima(a)