def generateAxialSineModel(amp, period, ylen, xlen, dy, phase=0.0): ''' Constructs a 1D sine model, oriented in the axial direction, from the format of an example image. ''' x, y = meshgrid(linspace(0, 1, xlen), linspace(0, 1, ylen)) g = models.Sine1D(amp, ylen * dy / period, phase) return g(y)
def fitB4(coord_iso): u = coord_iso[0] v = coord_iso[1] r = np.sqrt(u**2 + v**2) E=np.zeros(len(u)) for i in range(0,len(u)): if np.sign(u[i])>0 and np.sign(v[i])>0 : E[i]=np.arctan(v[i]/u[i]) elif np.sign(u[i])>0 and np.sign(v[i])<0 : E[i]=2*np.pi+np.arctan(v[i]/u[i]) else : E[i]=np.pi+np.arctan(v[i]/u[i]) Es = np.linspace(0,2*np.pi,num=100) dic = {'frequency': True, 'phase': True} g_init = (models.Sine1D(amplitude=0.1, frequency=1.5/np.pi, fixed=dic) +models.Sine1D(amplitude=0.1, frequency=2/np.pi, fixed=dic) +models.Sine1D(amplitude=0.1, frequency=1.5/np.pi, phase=0.25, fixed=dic) +models.Sine1D(amplitude=0.1, frequency=2/np.pi, phase=0.25, fixed=dic) +models.Const1D(amplitude=1.0,fixed={'amplitude':True})) fit = fitting.LevMarLSQFitter() or_fit = fitting.FittingWithOutlierRemoval(fit, sigma_clip, niter=3, sigma=3.0) filtered_data, or_fitted_model = or_fit(g_init, E, r) fitted_model = fit(g_init, E, r) plt.figure(figsize=(8,5)) plt.plot(E, r, 'gx', label="original data") plt.plot(E, filtered_data, 'r+', label="filtered data") plt.plot(Es, fitted_model(Es), 'g-', label="model fitted w/ original data") plt.plot(Es, or_fitted_model(Es), 'r--', label="model fitted w/ filtered data") plt.legend(loc=2, numpoints=1) return or_fitted_model[3].amplitude.value
astmodels.Moffat1D(amplitude=10., x_0=0.5, gamma=1.2, alpha=2.5), astmodels.Moffat2D(amplitude=10., x_0=0.5, y_0=1.5, gamma=1.2, alpha=2.5), astmodels.Planar2D(slope_x=0.5, slope_y=1.2, intercept=2.5), astmodels.RedshiftScaleFactor(z=2.5), astmodels.RickerWavelet1D(amplitude=10., x_0=0.5, sigma=1.2), astmodels.RickerWavelet2D(amplitude=10., x_0=0.5, y_0=1.5, sigma=1.2), astmodels.Ring2D(amplitude=10., x_0=0.5, y_0=1.5, r_in=5., width=10.), astmodels.Sersic1D(amplitude=10., r_eff=1., n=4.), astmodels.Sersic2D(amplitude=10., r_eff=1., n=4., x_0=0.5, y_0=1.5, ellip=0.0, theta=0.0), astmodels.Sine1D(amplitude=10., frequency=0.5, phase=1.), astmodels.Cosine1D(amplitude=10., frequency=0.5, phase=1.), astmodels.Tangent1D(amplitude=10., frequency=0.5, phase=1.), astmodels.ArcSine1D(amplitude=10., frequency=0.5, phase=1.), astmodels.ArcCosine1D(amplitude=10., frequency=0.5, phase=1.), astmodels.ArcTangent1D(amplitude=10., frequency=0.5, phase=1.), astmodels.Trapezoid1D(amplitude=10., x_0=0.5, width=5., slope=1.), astmodels.TrapezoidDisk2D(amplitude=10., x_0=0.5, y_0=1.5, R_0=5., slope=1.), astmodels.Voigt1D(x_0=0.55, amplitude_L=10., fwhm_L=0.5, fwhm_G=0.9), astmodels.BlackBody(scale=10.0, temperature=6000. * u.K), astmodels.Drude1D(amplitude=10.0, x_0=0.5, fwhm=2.5), astmodels.Plummer1D(mass=10.0, r_plum=5.0),
'LogParabola1D': models.LogParabola1D(1.0, 1.0, 1.0, 1.0), 'PowerLaw1D': models.PowerLaw1D(1.0, 1.0, 1.0), 'Linear1D': models.Linear1D(1.0, 0.0), 'Const1D': models.Const1D(0.0), 'Redshift': models.Redshift(0.0), 'Scale': models.Scale(1.0), 'Shift': models.Shift(0.0), 'Sine1D': models.Sine1D(1.0, 1.0), 'Chebyshev1D': models.Chebyshev1D(1), 'Legendre1D': models.Legendre1D(1), 'Polynomial1D': models.Polynomial1D(1), } # this nightmarish way of getting the function name results from the way # astropy functional models store them. Both their '_name' and 'name' # attributes are set to None, and a plain, easy to use name is nowhere # to be seen. And worse, the name coding changed dramatically from # astropy 0.4 to 1.0. def getComponentName(function):
#plt.axvspan(today+2, today+31, color='C0', alpha=0.5) #plt.axvspan(today+85, today+95, color='C0', alpha=0.5) plt.axvline(today) #plt.axvline(59000, ls = '-.', c='C0') #plt.axvline(58950, ls = '-.', c='C0') timefit = np.arange(times[0]-100, 59488, 10) #f_guess = frequency[np.argmax(power)] #f_guess = 1/550 periods = [] p_errors = [] for f_guess in (frequency[np.argmax(power)], 1/550, 1/1000, 1/130): sin_mod = models.Sine1D(amplitude=1e-12, frequency=f_guess) + models.Const1D(2e-12) sin_fit = fitter(sin_mod, times, flux, weights = 1/np.array(error), maxiter=100000) sin_fit_e = np.sqrt(np.diag(fitter.fit_info['param_cov'])) p_fit = 1/sin_fit[0].frequency periods.append(p_fit) p_e = sin_fit_e[1]/(sin_fit[0].frequency.value**2) p_errors.append(p_e) print(p_fit) print(p_e) label = 'P = {0:10.1f} d '.format(p_fit) idx = (np.abs(timefit - today)).argmin() print(sin_fit(timefit)[idx]) #label = 'P = {0:10.0f} $\pm$ {1:10.0f}d '.format(p_fit, p_e) plt.plot(timefit, sin_fit(timefit), label=label, ls='--')
def reconstruct(self, identifier, model=False): """ Reconstruct an approximate filter transmittance curve for a given filter. Parameters ---------- identifier : str Name of the filter. To see available filters, run `~tynt.Filter.available_filters()` model : bool Construct a composite astropy model which approximates the transmittance curve. Returns ------- filt : `~tynt.Filter` Astronomical filter object. """ filt = list(self.table.loc[identifier])[1:] n_lambda, lambda_0, delta_lambda, tr_max = filt[:4] fft = filt[4:] astropy_model = None wavelength = np.arange(lambda_0, (n_lambda + 1) * delta_lambda + lambda_0, delta_lambda) N = len(wavelength) ifft = np.fft.ifft(fft, n=len(wavelength)) transmittance = ((ifft.real - ifft.real.min()) * tr_max / ifft.real.ptp()) if model: m = (np.sum([ models.Sine1D( amplitude=fft[i].real / N, frequency=i / N, phase=1 / 4) for i in range(len(fft)) ]) - np.sum([ models.Sine1D(amplitude=fft[i].imag / N, frequency=i / N) for i in range(len(fft)) ])) @models.custom_model def fft_model(x): """ Approximate Fourier reconstruction of an astronomical filter Parameters ---------- x : `~np.ndarray` Wavelength in Angstroms. Returns ------- transmittance : `~np.ndarray` Transmittance curve """ mo = m( (x - wavelength.min()) / (wavelength[1] - wavelength[0])) return (mo - mo.min()) * tr_max / mo.ptp() astropy_model = fft_model() return Filter(wavelength * u.Angstrom, transmittance, model=astropy_model)
import numpy as np import joblib from copy import deepcopy, copy from os import system, path from astropy.table import Table import matplotlib.pyplot as plt from astropy.modeling import models, fitting data_dir = '/shared/data-camelot/cotar/Asiago_binaries_programme/RV_disentangle_results_newonly_renorm_noremovalfit/' rv_data = Table.read(data_dir + 'final_results.fits') key_fit = 'RV_s1' rv_data = rv_data[np.logical_and(np.isfinite(rv_data[key_fit]), rv_data['star'] == 'gz dra')] period = 2.25335 x = rv_data['JD'] % period / period y = rv_data[key_fit] fit_f = models.Sine1D(amplitude=40, frequency=1., phase=0.) + models.Const1D( amplitude=np.median(rv_data[key_fit])) fitter = fitting.LevMarLSQFitter() fit_res = fitter(fit_f, x, y) print(fit_res) x_eval = np.arange(0., 1, 0.01) plt.scatter(x, y, c='C3') plt.plot(x_eval, fit_res(x_eval), c='C2') plt.show() plt.close()
def adjusment(self, n): A = np.zeros(n) #amplitudes F = np.zeros(n) #phase origins fitter = fitting.LevMarLSQFitter() finit = models.Sine1D(frequency=1) for j in range(n - 1): finit = finit + models.Sine1D(frequency=j + 2) for j in range(n): finit[j].frequency.fixed = True ph2 = np.linspace(0, 2, 200) ffit = fitter(finit, self.ph, self.profilenorm, weights=1 / self.profile_err) for j in range(n): A[j] = ffit[j].amplitude.value F[j] = ffit[j].phase.value for j in range(n): while F[j] > 1.0: F[j] = F[j] - 1.0 while F[j] < 0.0: F[j] = F[j] + 1.0 if A[j] < 0: A[j] = -A[j] if F[j] > 0.5: F[j] = F[j] - 0.5 else: F[j] = F[j] + 0.5 #Error estimate S = 0 #chi square C_jk = np.zeros((2 * n, 2 * n)) Sigma = np.zeros(2 * n) #frequencies uncertainty for j in range(self.nbin): S = S + (self.profilenorm[j] - ffit(self.ph[j]))**2 / self.profile_err[j]**2 for j in range(2 * n): for k in range(2 * n): for h in range(self.nbin): if j < n and k < n: C_jk[j][k] = C_jk[j][k] + np.sin( 2 * np.pi * (j + 1) * self.ph[h] + F[j]) * np.sin(2 * np.pi * (k + 1) * self.ph[h] + F[k]) / self.profile_err[h]**2 elif j < n and k > n - 1: C_jk[j][k] = C_jk[j][k] + np.sin( 2 * np.pi * (j + 1) * self.ph[h] + F[j]) * A[k - n] * np.cos( 2 * np.pi * (k - n + 1) * self.ph[h] + F[k - n]) / self.profile_err[h]**2 elif j > n - 1 and k < n: C_jk[j][k] = C_jk[j][k] + A[j - n] * np.cos( 2 * np.pi * (j - n + 1) * self.ph[h] + F[j - n]) * np.sin(2 * np.pi * (k + 1) * self.ph[h] + F[k]) / self.profile_err[h]**2 else: C_jk[j][k] = C_jk[j][k] + A[j - n] * np.cos( 2 * np.pi * (j - n + 1) * self.ph[h] + F[j - n]) * A[k - n] * np.cos( 2 * np.pi * (k - n + 1) * self.ph[h] + F[k - n]) / self.profile_err[h]**2 for j in range(2 * n): Sigma[j] = (S * np.linalg.inv(C_jk)[j][j] / (self.nbin - n))**0.5 Sigma_A = Sigma[0:n] Sigma_F = Sigma[n:2 * n] return (ph2, ffit, A, F, Sigma_A, Sigma_F)
def baseline_sine(hdu, chan, windows, frequency=0.01, subtract=True, returnrms=True, kms=True): #this function needs to be passed a FITS HDU #with data in the (V,X,Y) format # frequency is the initial guess for frequency of the sine wave header = None if isinstance(hdu, pyfits.hdu.image.PrimaryHDU): # get data and header from the hdu header = hdu.header.copy() data = hdu.data.copy() elif isinstance(hdu, numpy.ndarray): if header is None or not isinstance(header, pyfits.header.Header): raise CubeVisArgumentError( 'header', "Since you passed in data that is a numpy array, set header to a pyfits header type" ) data = hdu.copy() shape = data.shape #windows over which to do the test for sigma values #basically excluse major lines you observe lenx, leny, lenv = shape #defaultswindow = ((100,200),(650,750)) sigma = numpy.zeros((lenx, leny)) # this commented section is the makermsimage way of selecting them # if someone wants to make a change regarding one being better, do it if chan: x = numpy.arange(lenv) else: x = getaxes(header, 1) indices = numpy.zeros(lenv, dtype=bool) for c_loop, win in enumerate(windows): if (len(win) != 2): print("Each element in the window list must be a 2-tuple") raise CubeVisArgumentError( 'window', "Each element in the window list must be a 2-tuple") v1, v2 = win v1, v2 = sorted((v1, v2)) ind = numpy.logical_and(x >= v1, x <= v2) if c_loop == 0: final_ind = numpy.logical_or(ind, ind) else: final_ind = numpy.logical_or(final_ind, ind) x_windows = x[final_ind] s_init = models.Sine1D(frequency=frequency) fit = fitting.LevMarLSQFitter() for ix in range(lenx): for iy in range(leny): spectra = data[ix, iy, :] spec_windows = spectra[final_ind] s = fit(s_init, x_windows, spec_windows) spec_windows -= s(x_windows) sigma[ix, iy] = spec_windows.std() if (subtract): data[ix, iy, :] -= s(x) # this is the original input - with data reduced as needed hdu_orig = pyfits.hdu.image.PrimaryHDU(header=header, data=data) if returnrms: #the following grabs relevant information from the original header #and reproduces it in the RMSMap header shifted to account for #the different shape of the data crpix1 = sxpar(header, "CRPIX1") crval1 = sxpar(header, "CRVAL1") cdelt1 = sxpar(header, "CDELT1") if kms: #convert velocity to km/s crval1 = crval1 / 1000. cdelt1 = cdelt1 / 1000. ctype1 = sxpar(header, "CTYPE1") cunit1 = sxpar(header, "CUNIT1") crpix2 = sxpar(header, "CRPIX2") crval2 = sxpar(header, "CRVAL2") cdelt2 = sxpar(header, "CDELT2") ctype2 = sxpar(header, "CTYPE2") cunit2 = sxpar(header, "CUNIT2") crpix3 = sxpar(header, "CRPIX3") crval3 = sxpar(header, "CRVAL3") cdelt3 = sxpar(header, "CDELT3") ctype3 = sxpar(header, "CTYPE3") cunit3 = sxpar(header, "CUNIT3") nv = sxpar(header, "NAXIS1") nx = sxpar(header, "NAXIS2") ny = sxpar(header, "NAXIS3") blank = sxpar(header, "BLANK") hnew = header.copy() sxaddpar(hnew, "CRVAL1", crval2, comment="DEGREES") sxaddpar(hnew, "CRPIX1", crpix2) sxaddpar(hnew, "CDELT1", cdelt2, comment="DEGREES") sxaddpar(hnew, "CTYPE1", ctype2) sxaddpar(hnew, "CUNIT1", cunit2) sxaddpar(hnew, "CRVAL2", crval3, comment="DEGREES") sxaddpar(hnew, "CRPIX2", crpix3) sxaddpar(hnew, "CDELT2", cdelt3, comment="DEGREES") sxaddpar(hnew, "CTYPE2", ctype3) sxaddpar(hnew, "CUNIT2", cunit3) sxaddpar(hnew, "NAXIS", 2) sxaddpar(hnew, "NAXIS1", nx) sxaddpar(hnew, "NAXIS2", ny) sxaddpar(hnew, "NAXIS3", 1) sxaddpar(hnew, "NAXIS4", 1) if chan: vorc = 'CHANNEL' else: vorc = 'VELOCITY' sxaddhist(hnew, "WINDOW : %s; Window %s LIMITS" % (repr(windows), vorc)) #sxaddpar(hnew, "BUNIT", units, "Units") sxdelpar(hnew, "CRVAL3") sxdelpar(hnew, "CRPIX3") sxdelpar(hnew, "CDELT3") sxdelpar(hnew, "CTYPE3") sxdelpar(hnew, "CUNIT3") sxdelpar(hnew, "NAXIS3") sxdelpar(hnew, "NAXIS4") hdu_rms = pyfits.hdu.image.PrimaryHDU(data=sigma, header=hnew) return (hdu_orig, hdu_rms) else: return hdu_orig