def test_calc_sig_levels_cases(): r"""Pytest cases for code/utils.py: calc_sig_levels """ # Define function for testing cases. def test_calc_sig_levels(model, sig_periods, ref_sig_powers, sigs=(95.0, 99.0), num_shuffles=100): r"""Pytest for code/utils.py: calc_sig_levels """ test_sig_powers = code.utils.calc_sig_levels(model=model, sig_periods=sig_periods, sigs=sigs, num_shuffles=num_shuffles) for key in ref_sig_powers: assert np.all(np.isclose(ref_sig_powers[key], test_sig_powers[key])) return None # Test adapted from # https://github.com/astroML/gatspy/blob/master/examples/MultiBand.ipynb rrlyrae = gatspy_data.fetch_rrlyrae() lcid = rrlyrae.ids[0] (times, mags, mags_err, filts) = rrlyrae.get_lightcurve(lcid) model = gatspy_per.LombScargleMultiband(Nterms_base=6, Nterms_band=1) model.fit(t=times, y=mags, dy=mags_err, filts=filts) (min_period, max_period, _) = code.utils.calc_period_limits(times=times) model.optimizer.period_range = (min_period, max_period) sigs = (95.0, 99.0) num_shuffles = 100 sig_periods = \ [1.66051856e+03, 2.99875187e-02, 1.49938947e-02, 9.99595991e-03, 7.49698121e-03, 5.99759039e-03, 4.99799500e-03, 4.28399755e-03, 3.74849907e-03, 3.33200001e-03] ref_sig_powers = \ {95.0: \ [0.25057282, 0.26775067, 0.25570964, 0.27631931, 0.26301363, 0.26418357, 0.2457524 , 0.24058861, 0.24839262, 0.24550175], 99.0: \ [0.32243259, 0.31730944, 0.29074282, 0.33228392, 0.29340864, 0.29399481, 0.26595011, 0.26355087, 0.29701109, 0.2730018]} test_calc_sig_levels(model=model, sig_periods=sig_periods, ref_sig_powers=ref_sig_powers, sigs=sigs, num_shuffles=num_shuffles) # TODO: insert additional test cases here. return None
def test_ls_model_fluxes_rel_cases(): r"""Pytest cases for code/utils.py: ls_model_fluxes_rel """ # Define function for testing cases. def test_ls_model_fluxes_rel(params, model, ref_modeled_fluxes_rel): r"""Pytest for code/utils.py: ls_model_fluxes_rel """ test_modeled_fluxes_rel = code.utils.ls_model_fluxes_rel(params=params, model=model) assert np.all( np.isclose(ref_modeled_fluxes_rel, test_modeled_fluxes_rel)) return None # Test adapted from # https://github.com/astroML/gatspy/blob/master/examples/MultiBand.ipynb rrlyrae = gatspy_data.fetch_rrlyrae() lcid = rrlyrae.ids[0] (times, mags, mags_err, filts) = rrlyrae.get_lightcurve(lcid) fluxes_rel = np.empty_like(mags) fluxes_rel_err = np.empty_like(mags_err) for filt in np.unique(filts): tfmask = (filt == filts) fluxes_rel[tfmask] = \ map(lambda mag_1: \ bss.utils.calc_flux_intg_ratio_from_mags( mag_1=mag_1, mag_2=np.median(mags[tfmask])), mags[tfmask]) fluxes_rel_err[tfmask] = \ map(lambda mag_1, mag_2: \ abs(1.0 - bss.utils.calc_flux_intg_ratio_from_mags( mag_1=mag_1, mag_2=mag_2)), np.add(mags[tfmask], mags_err[tfmask]), mags[tfmask]) model = gatspy_per.LombScargleMultiband(Nterms_base=6, Nterms_band=1) best_period = rrlyrae.get_metadata(lcid)['P'] params = (best_period) model.fit(t=times, y=fluxes_rel, dy=fluxes_rel_err, filts=filts) test_ls_model_fluxes_rel(params=params, model=model, ref_modeled_fluxes_rel=model.predict( t=model.t, filts=model.filts, period=best_period)) # TODO: insert additional test cases here. return None
def process(df, filters=list('IV')): if TYPE == 'fast': model = periodic.LombScargleMultibandFast( fit_period=True, Nterms=1, optimizer_kwds=dict(quiet=True)) model.optimizer.period_range = (0.1, 10) if TYPE == 'slow': model = periodic.LombScargleMultiband( fit_period=True, optimizer_kwds=dict(quiet=True)) model.optimizer.period_range = (0.1, 10) if TYPE == 'naive': #model = periodic.NaiveMultiband(fit_period=True) model = correctedNaiveMultiband(fit_period=True, optimizer_kwds=dict(quiet=True)) model.fit(df['t'], df['mag'], df['magerr'], df['filt']) if TYPE == 'naive': best_period = np.mean(model.best_period) else: best_period = model.best_period if phase_plot: tfit = np.linspace(0, model.best_period, 1000) filtsfit = np.array(filters)[:, np.newaxis] magfit = model.predict(tfit, filts=filtsfit) if np.size(model.best_period) > 1: phase = (df['t'][np.newaxis, :] / model.best_period[:, np.newaxis]) % 1 phasefit = (tfit.T / model.best_period[:, np.newaxis]) else: phase = (df['t'] / model.best_period) % 1 phasefit = (tfit / model.best_period) if Periodogram_auto: return best_period, tfit, filtsfit, magfit, phasefit, model.periodogram_auto( ) return best_period, tfit, filtsfit, magfit, phasefit, [ o, model.periodogram(o) ] return best_period
def refine_period_LS(self, filters=[1, 2], logtrange=-5, Nharm=5): import astropy.units as u from astropy.timeseries import BoxLeastSquares from gatspy import periodic # pmin,pmax pmin = self.p * (1 - 10**logtrange), pmax = self.p * (1 + 10**logtrange), # model setup model = periodic.LombScargleMultiband(fit_period=True) model.optimizer.period_range = (pmin, pmax) mask = np.isin(self.fid, filters) model.fit(self.t[mask], self.y[mask], self.dy[mask], self.fid[mask]) p = model.best_period print('period set to %12.12f, a %f fractional change' % (p, (self.p - p) / self.p)) self.p = p
def fit_model(self): """Fit the lightcurve data using periodic.LombScargleMultiband. """ # Let's try to fit these values with the gatspy multiband fitter self.model = periodic.LombScargleMultiband( fit_period=True, Nterms_base=self.Nterms_base, Nterms_band=self.Nterms_band) big_period = np.min( [self.max_period, (self.lcobs.jd.max() - self.lcobs.jd.min())]) self.model.optimizer.period_range = (self.min_period, big_period) self.model.optimizer.first_pass_coverage = 200 self.model.fit(self.lcobs.jd, self.lcobs.magcorr, self.lcobs.sigmamag, self.lcobs.fid) self.best_period = self.model.best_period times = np.arange(0, self.best_period, self.best_period / 100) predictions = self.make_predictions(times, self.best_period) # Should we probably double this peak? idx = find_peaks(predictions[self.filterlist[0]])[0] self.npeaks = len(idx) if len(idx) == 1: self.best_period *= 2 # Calculate amplitude self.amp = 0 for k in predictions: amp = predictions[k].max() - predictions[k].min() self.amp = max(amp, self.amp) # Calculate chisq of fit self.calc_chisq() # Calculate updated colors self.gr = -999 self.ri = -999 if self.photoffsets is not None: if 1 in self.photoffsets and 2 in self.photoffsets: self.gr = self.photoffsets[1] - self.photoffsets[2] # And check if we can refine this from the lc fit self.gr = self.gr + (predictions[1] - predictions[2])[0] if 3 in self.photoffsets and 2 in self.photoffsets: self.ri = self.photoffsets[2] - self.photoffsets[3] self.ri = self.ri + (predictions[2] - predictions[3])[0]
def periodscan(self, min_p, max_p, periods=None): """ Computes a LombScargle periodgram from minp to maxp, or alternatively on the array of periods sets model, periods, P_multi and best_period, overwriting if they already exist """ nobs = len(self.time) if nobs == 0: return None, None, None # if self.time.max() - self.time.min() < max_p: # return None, None, None optimizer_kwds = {'quiet':True} try: if nobs <= 100: model = periodic.LombScargleMultiband(fit_period=True, optimizer_kwds=optimizer_kwds) else: print('nobs', nobs, self.objectId) model = periodic.LombScargleMultibandFast(fit_period=True, optimizer_kwds=optimizer_kwds) model.optimizer.period_range = (min_p, max_p) model.fit(self.time, self.flux, self.fluxErr, self.passband) if periods is None: periods, P_multi = model.periodogram_auto() else: P_multi = model.periodogram(periods) self.model = model self.best_period = model.best_period self.periods = periods self.P_multi = P_multi return model, periods, P_multi except Exception as e: message = '{}\nCould not run periodscan for {} at locus ID {}'.format(e, self.objectId, self.locusId) warnings.warn(message, RuntimeWarning) return None, None, None
def apply(self, lc: lightcurve._LC) -> MultiBandPeriod: def _concat_for_all_bands(key_fcn): return np.concatenate( [key_fcn(name, band) for name, band in lc.bands.items()]) times = _concat_for_all_bands(lambda _, band: band.time) fluxes = _concat_for_all_bands(lambda _, band: band.flux) flux_errs = _concat_for_all_bands(lambda _, band: band.flux_err) bands = _concat_for_all_bands( lambda name, band: np.full_like(band.time, name, dtype=str)) model = periodic.LombScargleMultiband(fit_period=False) model.optimizer.period_range = (.1, np.max(times) - np.min(times)) model.optimizer.quiet = True model.fit(times, fluxes, flux_errs, bands) period, power = model.periodogram_auto() best_periods, scores = model.find_best_periods(5, return_scores=True) return MultiBandPeriod( period=period, band_to_power={name: power for name in lc.bands.keys()}, best_periods=best_periods, scores=scores)
ax[0].errorbar(df2.ix[:, 2], df2.ix[:, 0], yerr=df2.ix[:, 1], fmt='.') ax[0].set_ylim(19.5, 17.6) ax[0].set_xlabel('Band Wavelength') ax[0].set_ylabel('Band Magnitude') plt.show() #Period estimation for a single lightcurve file time = np.array(map(float, df.ix[:, 0].values)) mags = np.array(map(float, df.ix[:, 2].values)) dmags = np.array(map(float, df.ix[:, 3].values)) filters = np.array(df.ix[:, 1].values) masks = [(filters == band) for band in 'ugriz'] #sys.stdout = open(os.devnull,"w") #To prevent printing intermediate results by in-built functions ls = periodic.LombScargleMultiband(fit_period=True) #For finding periodicity in irregularly sampled multiband data ls.optimizer.period_range = (0.2, 1.0) ls.fit(time, mags, dmags, filters) period = ls.best_period #sys.stdout = sys.__stdout__ print period #Calculating the phase foldTimes = time / period foldTimes = foldTimes % 1 foldTimes = np.array(foldTimes) #Plotting the folded light curves for each band fig = plt.figure(figsize=(14, 5)) gs = plt.GridSpec(5,
def test_calc_min_flux_time_cases(): r"""pytest cases for code/utils.py: calc_min_flux_time """ # Define function for testing cases. def test_calc_min_flux_time(model, filt, ref_min_flux_time, best_period=None, lwr_time_bound=None, upr_time_bound=None, tol=0.1, maxiter=10): r"""Pytest for code/utils.py: calc_min_flux_time """ test_min_flux_time = \ code.utils.calc_min_flux_time( model=model, filt=filt, best_period=best_period, lwr_time_bound=lwr_time_bound, upr_time_bound=upr_time_bound, tol=tol, maxiter=maxiter) assert np.isclose(ref_min_flux_time, test_min_flux_time) return None # Test adapted from # https://github.com/astroML/gatspy/blob/master/examples/MultiBand.ipynb rrlyrae = gatspy_data.fetch_rrlyrae() lcid = rrlyrae.ids[0] (times, mags, mags_err, filts) = rrlyrae.get_lightcurve(lcid) fluxes_rel = np.empty_like(mags) fluxes_rel_err = np.empty_like(mags_err) for filt in np.unique(filts): tfmask = (filt == filts) fluxes_rel[tfmask] = \ map(lambda mag_1: \ bss.utils.calc_flux_intg_ratio_from_mags( mag_1=mag_1, mag_2=np.median(mags[tfmask])), mags[tfmask]) fluxes_rel_err[tfmask] = \ map(lambda mag_1, mag_2: \ abs(1.0 - bss.utils.calc_flux_intg_ratio_from_mags( mag_1=mag_1, mag_2=mag_2)), np.add(mags[tfmask], mags_err[tfmask]), mags[tfmask]) model = gatspy_per.LombScargleMultiband(Nterms_base=6, Nterms_band=1) best_period = rrlyrae.get_metadata(lcid)['P'] model.fit(t=times, y=fluxes_rel, dy=fluxes_rel_err, filts=filts) min_flux_time_init = \ code.utils.calc_min_flux_time( model=model, filt='z', best_period=best_period, tol=0.1, maxiter=10) for (filt, ref_min_flux_time) in \ zip(['u', 'g', 'r', 'i', 'z'], [0.370657590606, 0.366563989108, 0.375194445097, 0.377970590837, 0.378704402065]): time_window_halfwidth = 0.1 * best_period test_calc_min_flux_time( model=model, filt=filt, ref_min_flux_time=ref_min_flux_time, best_period=best_period, lwr_time_bound=min_flux_time_init - time_window_halfwidth, upr_time_bound=min_flux_time_init + time_window_halfwidth, tol=1e-5, maxiter=10) # TODO: insert additional test cases here. return None
import h5py import matplotlib.pyplot as plt import numpy as np from glob import glob paths = glob('/Users/bmmorris/data/freckles/*.fits') from astropy.io import fits spectrum_times = [fits.getheader(p)['JD'] for p in paths] times_g, lc_g = np.loadtxt('lc.txt', unpack=True) times_u, lc_u = np.loadtxt('lc_u.txt', unpack=True) err = np.std(lc_g)/2 from gatspy import periodic # Fit the Lomb-Scargle model model = periodic.LombScargleMultiband(Nterms_base=3)#, fit_period=False) model.fit(np.concatenate([times_g, times_u]), np.concatenate([lc_g, lc_u]), filts=np.concatenate([np.zeros_like(times_g), np.ones_like(times_u)])) P_rot = 1.407 # (Nielson 2013) model.optimizer.period_range = (1.3, 1.5) # Predict on a regular phase grid period = model.best_period tfit = np.linspace(0, period, 1000) magfit_g = model.predict(tfit, filts=0) magfit_u = model.predict(tfit, filts=1) # Plot the results phase_g = (times_g / period) % 1 phasefit_g = (tfit / period)
def plot_variable_star(nterms_base, nterms_band, manual_period, n_clicks, object_data): """ Fit for the period of a star using gatspy See https://zenodo.org/record/47887 See https://ui.adsabs.harvard.edu/abs/2015ApJ...812...18V/abstract TODO: clean me """ if type(nterms_base) not in [int]: return {'data': [], "layout": layout_phase} if type(nterms_band) not in [int]: return {'data': [], "layout": layout_phase} if manual_period is not None and type(manual_period) not in [int, float]: return {'data': [], "layout": layout_phase} if n_clicks is not None: pdf_ = pd.read_json(object_data) cols = [ 'i:jd', 'i:magpsf', 'i:sigmapsf', 'i:fid', 'i:magnr', 'i:sigmagnr', 'i:magzpsci', 'i:isdiffpos', 'i:objectId' ] pdf = pdf_.loc[:, cols] pdf['i:fid'] = pdf['i:fid'].astype(str) pdf = pdf.sort_values('i:jd', ascending=False) mag_dc, err_dc = np.transpose([ dc_mag(*args) for args in zip( pdf['i:fid'].astype(int).values, pdf['i:magpsf'].astype( float).values, pdf['i:sigmapsf'].astype(float).values, pdf['i:magnr'].astype(float).values, pdf['i:sigmagnr'].astype( float).values, pdf['i:magzpsci'].astype( float).values, pdf['i:isdiffpos'].values) ]) jd = pdf['i:jd'] fit_period = False if manual_period is not None else True model = periodic.LombScargleMultiband(Nterms_base=int(nterms_base), Nterms_band=int(nterms_band), fit_period=fit_period) # Not sure about that... model.optimizer.period_range = (0.1, 1.2) model.optimizer.quiet = True model.fit(jd.astype(float), mag_dc, err_dc, pdf['i:fid'].astype(int)) if fit_period: period = model.best_period else: period = manual_period phase = jd.astype(float).values % period tfit = np.linspace(0, period, 100) layout_phase_ = copy.deepcopy(layout_phase) layout_phase_['title']['text'] = 'Period: {} days'.format(period) if '1' in np.unique(pdf['i:fid'].values): plot_filt1 = { 'x': phase[pdf['i:fid'] == '1'], 'y': mag_dc[pdf['i:fid'] == '1'], 'error_y': { 'type': 'data', 'array': err_dc[pdf['i:fid'] == '1'], 'visible': True, 'color': '#1f77b4' }, 'mode': 'markers', 'name': 'g band', 'text': phase[pdf['i:fid'] == '1'], 'marker': { 'size': 12, 'color': '#1f77b4', 'symbol': 'o' } } fit_filt1 = { 'x': tfit, 'y': model.predict(tfit, period=period, filts=1), 'mode': 'lines', 'name': 'fit g band', 'showlegend': False, 'line': { 'color': '#1f77b4', } } else: plot_filt1 = {} fit_filt1 = {} if '2' in np.unique(pdf['i:fid'].values): plot_filt2 = { 'x': phase[pdf['i:fid'] == '2'], 'y': mag_dc[pdf['i:fid'] == '2'], 'error_y': { 'type': 'data', 'array': err_dc[pdf['i:fid'] == '2'], 'visible': True, 'color': '#ff7f0e' }, 'mode': 'markers', 'name': 'r band', 'text': phase[pdf['i:fid'] == '2'], 'marker': { 'size': 12, 'color': '#ff7f0e', 'symbol': 'o' } } fit_filt2 = { 'x': tfit, 'y': model.predict(tfit, period=period, filts=2), 'mode': 'lines', 'name': 'fit r band', 'showlegend': False, 'line': { 'color': '#ff7f0e', } } else: plot_filt2 = {} fit_filt2 = {} figure = { 'data': [plot_filt1, fit_filt1, plot_filt2, fit_filt2], "layout": layout_phase_ } return figure return {'data': [], "layout": layout_phase}