def getPeriod(HJD, TMag, TdMag, p_range=None, makeGraph=None, giveP=None): if p_range is None: p_min = .01 p_max = 2 else: p_min, p_max = p_range if makeGraph is None: makeGraph = False if giveP is None: giveP = False lsf = LombScargleFast() lsf.optimizer.period_range = (p_min, p_max) lsf.fit(HJD, TMag, TdMag) period = lsf.best_period if giveP: print("\n") print("Period: " + str(period)) print("\n") if makeGraph: periods = np.linspace(p_min, p_max, 1000) scores = lsf.score(periods) plt.plot(periods, scores) plt.xlabel("Period") plt.ylabel("Probability") plt.show() return period
def period_search_ls(t, mag, magerr, remove_harmonics=True): ls = LombScargleFast(silence_warnings=True) T = np.max(t) - np.min(t) ls.optimizer.period_range = (0.01, T) ls.fit(t, mag, magerr) period = ls.best_period power = ls.periodogram(period) # https://github.com/astroML/gatspy/blob/master/examples/FastLombScargle.ipynb oversampling = 3.0 N = len(t) df = 1. / (oversampling * T) # frequency grid spacing fmin = 2 / T fmax = 480 # minimum period is 0.05 d Nf = (fmax - fmin) // df freqs = fmin + df * np.arange(Nf) periods = 1 / freqs powers = ls._score_frequency_grid(fmin, df, Nf) ind_best = np.argsort(powers)[-1] period = periods[ind_best] power = powers[ind_best] # calcualte false alarm probability (FAP) Z = power normalization = 'standard' # fap_Neff is underestimate fap_Neff = FAP_estimated(Z, N, fmax, t, normalization=normalization) """ # fap_Baluev is overestimate fap_Baluev = FAP_aliasfree(Z, N, fmax, t, mag, magerr, normalization=normalization) """ psigma = (np.percentile(powers, 84) - np.percentile(powers, 16)) / 2 significance = power / psigma if remove_harmonics == True: # In some cases, the period search is not successful: harmonics = np.array([1 / 5, 1 / 4, 1 / 3, 1 / 2, 1., 2.]) if abs(period - T) < 0.005: period = -99 else: for harmonic in harmonics: if abs(period - harmonic) < 0.005: if fap_Neff > 0.001: period = -99 data_out = {} data_out["period"] = period data_out["significance"] = significance data_out["freqs"] = freqs data_out["powers"] = powers data_out["power"] = power data_out["Nztfobs"] = N data_out["fap_Neff"] = fap_Neff # data_out["fap_Baluev"] = fap_Baluev return data_out
def FindPeriod(time,flux, minper=0.1,maxper=30,debug=False): ''' Finds period in time series data using Lomb-Scargle method ''' pgram = LombScargleFast(fit_period=True,\ optimizer_kwds={"quiet": not debug}) pgram.optimizer.period_range = (minper, maxper) pgram.fit(time,flux) if debug: print ("Best period:", pgram.best_period) return pgram.best_period
def fit_lomb_scargle(self): from gatspy.periodic import LombScargleFast period_range = (0.005 * (max(self.times) - min(self.times)), 0.95 * (max(self.times) - min(self.times))) model_gat = LombScargleFast(fit_period=True, silence_warnings=True, optimizer_kwds={ 'period_range': period_range, 'quiet': True }) model_gat.fit(self.times, self.measurements, self.errors) self.best_period = model_gat.best_period self.best_score = model_gat.score(model_gat.best_period).item()
def get_timing_lombscargle(n, ofac, hfac): x, y, dy = generate_random_signal(n) Nf = int(floor(0.5 * len(x) * ofac * hfac)) df = 1. / (ofac * (max(x) - min(x))) f0 = df model = LombScargleFast(silence_warnings=True) model.fit(x, y, dy) t0 = time() model.score_frequency_grid(f0, df, Nf) dt = time() - t0 return dt
def FlarePer(time, minper=0.1, maxper=30.0, nper=20000): ''' Look for periodicity in the flare occurrence times. Could be due to: a) mis-identified periodic things (e.g. heartbeat stars) b) crazy binary star flaring things c) flares on a rotating star d) bugs in code e) aliens ''' # use energy = 1 for flare times. # This will create something like the window function energy = np.ones_like(time) # Use Jake Vanderplas faster version! pgram = LombScargleFast(fit_offset=False) pgram.optimizer.set(period_range=(minper, maxper)) pgram = pgram.fit(time, energy - np.nanmedian(energy)) df = (1. / minper - 1. / maxper) / nper f0 = 1. / maxper pwr = pgram.score_frequency_grid(f0, df, nper) freq = f0 + df * np.arange(nper) per = 1. / freq pk = per[np.argmax(pwr)] # peak period pp = np.max(pwr) # peak period power return pk, pp
def FitSin(time, flux, error, maxnum=5, nper=20000, minper=0.1, maxper=30.0, plim=0.25, per2=False, returnmodel=True, debug=False): ''' Use Lomb Scargle to find a periodic signal. If it is significant then fit a sine curve and subtract. Repeat this procedure until no more periodic signals are found, or until maximum number of iterations has been reached. Note: this is where major issues were found in the light curve fitting as of Davenport (2016), where the iterative fitting was not adequately subtracting "pointy" features, such as RR Lyr or EBs. Upgrades to the fitting step are needed! Or, don't use iterative sine fitting... Idea for future: if L-S returns a significant P, use a median fit of the phase-folded data at that P instead of a sine fit... Parameters ---------- time : 1-d numpy array flux : 1-d numpy array error : 1-d numpy array maxnum : int, optional maximum number of iterations to try finding periods at (default=5) nper : int, optional number of periods to search over with Lomb Scargle (defeault=20000) minper : float, optional minimum period (in units of time array, nominally days) to search for periods over (default=0.1) maxper : float, optional maximum period (in units of time array, nominally days) to search for periods over (default=30.0) plim : float, optional Lomb-Scargle power threshold needed to define a "significant" period (default=0.25) per2 : bool, optional if True, use the 2-sine model fit at each period. if False, use normal 1-sine model (default=False) returnmodel : bool, optional if True, return the combined sine model. If False, return the data - model (default=True) debug : bool, optional used to print out troubleshooting things (default=False) Returns ------- If returnmodel=True, output = combined sine model (default=True) If returnmodel=False, output = (data - model) ''' flux_out = np.array(flux, copy=True) sin_out = np.zeros_like(flux) # return the sin function! # total baseline of time window dt = np.nanmax(time) - np.nanmin(time) medflux = np.nanmedian(flux) # ti = time[dl[i]:dr[i]] for k in range(0, maxnum): # Use Jake Vanderplas faster version! pgram = LombScargleFast(fit_offset=False) pgram.optimizer.set(period_range=(minper, maxper)) pgram = pgram.fit(time, flux_out - medflux, error) df = (1. / minper - 1. / maxper) / nper f0 = 1. / maxper pwr = pgram.score_frequency_grid(f0, df, nper) freq = f0 + df * np.arange(nper) per = 1. / freq pok = np.where((per < dt) & (per > minper)) pk = per[pok][np.argmax(pwr[pok])] pp = np.max(pwr) if debug is True: print('trial (k): ' + str(k) + '. peak period (pk):' + str(pk) + '. peak power (pp):' + str(pp)) # if a period w/ enough power is detected if (pp > plim): # fit sin curve to window and subtract if per2 is True: p0 = [ pk, 3.0 * np.nanstd(flux_out - medflux), 0.0, pk / 2., 1.5 * np.nanstd(flux_out - medflux), 0.1, 0.0 ] try: pfit, pcov = curve_fit(_sinfunc2, time, flux_out - medflux, p0=p0) if debug is True: print('>>', pfit) except RuntimeError: pfit = [pk, 0., 0., 0., 0., 0., 0.] if debug is True: print('Curve_Fit2 no good') flux_out = flux_out - _sinfunc2(time, *pfit) sin_out = sin_out + _sinfunc2(time, *pfit) else: p0 = [pk, 3.0 * np.nanstd(flux_out - medflux), 0.0, 0.0] try: pfit, pcov = curve_fit(_sinfunc, time, flux_out - medflux, p0=p0) except RuntimeError: pfit = [pk, 0., 0., 0.] if debug is True: print('Curve_Fit no good') flux_out = flux_out - _sinfunc(time, *pfit) sin_out = sin_out + _sinfunc(time, *pfit) # add the median flux for this window BACK in sin_out = sin_out + medflux # if debug is True: # plt.figure() # plt.plot(time, flux) # plt.plot(time, flux_out, c='red') # plt.show() if returnmodel is True: return sin_out else: return flux_out
def FitSin(time, flux, error, maxnum=5, nper=20000, minper=0.1, maxper=30.0, plim=0.25, returnmodel=True, debug=False, per2=False): ''' Use Lomb Scargle to find periods, fit sins, remove, repeat. Parameters ---------- time: flux: error: maxnum: nper: int, optional number of periods to search over with Lomb Scargle minper: maxper: plim: debug: Returns ------- ''' # periods = np.linspace(minper, maxper, nper) flux_out = np.array(flux, copy=True) sin_out = np.zeros_like(flux) # return the sin function! # total baseline of time window dt = np.nanmax(time) - np.nanmin(time) medflux = np.nanmedian(flux) # ti = time[dl[i]:dr[i]] for k in range(0, maxnum): # Use Jake Vanderplas faster version! pgram = LombScargleFast(fit_offset=False) pgram.optimizer.set(period_range=(minper, maxper)) pgram = pgram.fit(time, flux_out - medflux, error) df = (1. / minper - 1. / maxper) / nper f0 = 1. / maxper pwr = pgram.score_frequency_grid(f0, df, nper) freq = f0 + df * np.arange(nper) per = 1. / freq pok = np.where((per < dt) & (per > minper)) pk = per[pok][np.argmax(pwr[pok])] pp = np.max(pwr) if debug is True: print('trial (k): ' + str(k) + '. peak period (pk):' + str(pk) + '. peak power (pp):' + str(pp)) # if a period w/ enough power is detected if (pp > plim): # fit sin curve to window and subtract if per2 is True: p0 = [ pk, 3.0 * np.nanstd(flux_out - medflux), 0.0, pk / 2., 1.5 * np.nanstd(flux_out - medflux), 0.1, 0.0 ] try: pfit, pcov = curve_fit(_sinfunc2, time, flux_out - medflux, p0=p0) if debug is True: print('>>', pfit) except RuntimeError: pfit = [pk, 0., 0., 0., 0., 0., 0.] if debug is True: print('Curve_Fit2 no good') flux_out = flux_out - _sinfunc2(time, *pfit) sin_out = sin_out + _sinfunc2(time, *pfit) else: p0 = [pk, 3.0 * np.nanstd(flux_out - medflux), 0.0, 0.0] try: pfit, pcov = curve_fit(_sinfunc, time, flux_out - medflux, p0=p0) except RuntimeError: pfit = [pk, 0., 0., 0.] if debug is True: print('Curve_Fit no good') flux_out = flux_out - _sinfunc(time, *pfit) sin_out = sin_out + _sinfunc(time, *pfit) # add the median flux for this window BACK in sin_out = sin_out + medflux # if debug is True: # plt.figure() # plt.plot(time, flux) # plt.plot(time, flux_out, c='red') # plt.show() if returnmodel is True: return sin_out else: return flux_out
def run_gatspy(self): #this is the general simulation - ellc light curves and gatspy periodograms #for the multiband gatspy fit allObsDates = np.array([]) allAppMagObs = np.array([]) allAppMagObsErr = np.array([]) allObsFilters = np.array([]) minNobs = 1e10 if (self.verbose): print("in run_gatspy") for i, filt in enumerate(self.filters): self.EB.LSS[filt] = -999. if (self.EB.obsDates[filt][0] is not None and min(self.EB.appMagObs[filt]) > 0): #run gatspy for this filter drng = max(self.EB.obsDates[filt]) - min( self.EB.obsDates[filt]) minNobs = min(minNobs, len(self.EB.obsDates[filt])) #print("filter, nobs", filt, len(self.EB.obsDates[filt])) if (self.useFast and len(self.EB.obsDates[filt]) > 50): model = LombScargleFast(fit_period=True, silence_warnings=True, optimizer_kwds={"quiet": True}) else: model = LombScargle(fit_period=True, optimizer_kwds={"quiet": True}) pmin = self.gatspyPeriodMin if (self.EB.period < pmin): pmin = 0.1 * self.EB.period model.optimizer.period_range = (pmin, drng) model.fit(self.EB.obsDates[filt], self.EB.appMagObs[filt], self.EB.appMagObsErr[filt]) self.EB.LSS[filt] = model.best_period self.EB.LSSmodel[filt] = model self.EB.maxDeltaMag = max(self.EB.deltaMag[filt], self.EB.maxDeltaMag) #to use for the multiband fit allObsDates = np.append(allObsDates, self.EB.obsDates[filt]) allAppMagObs = np.append(allAppMagObs, self.EB.appMagObs[filt]) allAppMagObsErr = np.append(allAppMagObsErr, self.EB.appMagObsErr[filt]) allObsFilters = np.append( allObsFilters, np.full(len(self.EB.obsDates[filt]), filt)) if (self.verbose): print('filter = ', filt) print('obsDates = ', self.EB.obsDates[filt][0:10]) print('appMagObs = ', self.EB.appMagObs[filt][0:10]) print('delta_mag = ', self.EB.deltaMag[filt]) print('LSS = ', self.EB.LSS[filt]) if (len(allObsDates) > 0 and self.doLSM): drng = max(allObsDates) - min(allObsDates) if (self.useFast and minNobs > 50): model = LombScargleMultibandFast( fit_period=True, optimizer_kwds={"quiet": True}) else: model = LombScargleMultiband(Nterms_band=self.n_band, Nterms_base=self.n_base, fit_period=True, optimizer_kwds={"quiet": True}) pmin = self.gatspyPeriodMin if (self.EB.period < pmin): pmin = 0.1 * self.EB.period model.optimizer.period_range = (pmin, drng) model.fit(allObsDates, allAppMagObs, allAppMagObsErr, allObsFilters) self.EB.LSM = model.best_period self.EB.LSMmodel = model if (self.verbose): print('LSM =', self.EB.LSM)
def ellc_gatspy_sim(j, t_zero, period, a, q, f_c, f_s, ld_1, ld_2, Teff1, Teff2, logg1, logg2, M_H, R_1, R_2, incl, sbratio, shape_1, shape_2, appmag, bnum, n_band, n_base, return_dict, plot_dict, db, dbID_OpSim): #this is the general simulation - ellc light curves and gatspy periodograms #global filters, sigma_sys, totaltime, cadence print("here in ellc_gatspy_sim") totalt = [] totalmag = [] totaldmag = [] totalfilts = [] if (verbose): print(j, 't_zero = ', t_zero) print(j, 'period = ', period) print(j, 'semimajor = ', a) print(j, 'massrat = ', q) print(j, 'f_c = ', f_c) print(j, 'f_s = ', f_s) print(j, 'ld_1 = ', ld_1) print(j, 'ld_2 = ', ld_2) print(j, 'radius_1 = ', R_1) print(j, 'radius_2 = ', R_2) print(j, 'incl = ', incl) print(j, 'sbratio = ', sbratio) print(j, 'Teff1 = ', Teff1) print(j, 'Teff2 = ', Teff2) if (do_plot): # for plotting the periodograms for_plotting = dict() pds = np.linspace(0.2, 2. * period, 10000) for_plotting['periods'] = pds for_plotting['seed'] = bnum #set the random seed #np.random.seed(seed = seed) delta_mag = 0. if (opsim): cursor = getSummaryCursor(db, dbID_OpSim) for i, filt in enumerate(filters): if (opsim): print("I'm running code with OpSim!") time = getexpDate(cursor, dbID_OpSim, filt) nobs = len(time) print("time_OpSim = ", time) else: print("I'm NOT running code with OpSim!") nobs = int(round(totaltime / (cadence * len(filters)))) time = np.sort(totaltime * np.random.random(size=nobs)) #time.sort() #maybe not needed and taking time drng = max(time) - min(time) # if (time_OpSim[0] != None): if (time[0] != None): filtellc = filt if (filt == 'y_'): filtellc = 'z_' #because we don't have limb darkening for y_ ########################## #Can we find limb darkening coefficients for y band?? (Then we wouldn't need this trick) ########################## ldy_filt = ellc.ldy.LimbGravityDarkeningCoeffs(filtellc) a1_1, a2_1, a3_1, a4_1, y = ldy_filt(Teff1, logg1, M_H) a1_2, a2_2, a3_2, a4_2, y = ldy_filt(Teff2, logg2, M_H) ldc_1 = [a1_1, a2_1, a3_1, a4_1] ldc_2 = [a1_2, a2_2, a3_2, a4_2] lc = ellc.lc(time, t_zero=t_zero, period=period, a=a, q=q, f_c=f_c, f_s=f_s, ld_1=ld_1, ldc_1=ldc_1, ld_2=ld_2, ldc_2=ldc_2, radius_1=R_1, radius_2=R_2, incl=incl, sbratio=sbratio, shape_1=shape_1, shape_2=shape_2, grid_1='default', grid_2='default') if (verbose): print(j, 'ldc_1 = ', ldc_1) print(j, 'ldc_2 = ', ldc_2) print(j, 'time = ', time[0:10]) print(j, 'lc = ', lc[0:10]) if (min(lc) >= 0): magn = -2.5 * np.log10(lc) magnitude = appmag + magn #Ivezic 2008, https://arxiv.org/pdf/0805.2366.pdf , Table 2 sigma2_rand = getSig2Rand(filt, magnitude) #random photometric error sigma = ((sigma_sys**2.) + (sigma2_rand))**(1. / 2.) #now add the uncertaintly onto the magnitude #magnitude_obs = magnitude magnitude_obs = [ np.random.normal(loc=x, scale=sig) for (x, sig) in zip(magnitude, sigma) ] delta_mag = max( [delta_mag, abs(min(magnitude_obs) - max(magnitude_obs))]) if (verbose): print(j, 'magn = ', magn[0:10]) print(j, 'magnitude = ', magnitude[0:10]) print(j, 'magnitude_obs = ', magnitude_obs[0:10]) print(j, "sigma2_rand = ", sigma2_rand[0:10]) print(j, "sigma = ", sigma[0:10]) print(j, "delta_mag = ", delta_mag) t = np.array(time) totalt.extend(t) mag = np.array(magnitude_obs) totalmag.extend(mag) dmag = np.array(sigma) totaldmag.extend(dmag) filts = np.array(filt) specfilt = nobs * [filt] totalfilts.extend(specfilt) #model = LombScargle(fit_period = True) model = LombScargleFast(fit_period=True) model.optimizer.period_range = (0.2, drng) model.fit(t, mag, dmag) LSS = model.best_period print('LSS running') return_dict[j] = return_dict[j] + [LSS] print('LSS in return_dict') if (verbose): print(j, "LSS = ", LSS) if (do_plot): if (i == 0): for_plotting['phase_obs'] = dict() for_plotting['mag_obs'] = dict() for_plotting['mag'] = dict() for_plotting['scores'] = dict() for_plotting['LSS'] = dict() phase_obs = np.array([(tt % period) / period for tt in time]) scores = model.score(pds) for_plotting['phase_obs'][filt] = phase_obs for_plotting['mag_obs'][filt] = magnitude_obs for_plotting['mag'][filt] = magnitude for_plotting['scores'][filt] = scores for_plotting['LSS'][filt] = LSS else: return_dict[j] = return_dict[j] + [-999.] if (verbose): print(j, "bad fluxes", filt) #raise Exception('stopping') if (len(totalmag) > 0): t = np.array(totalt) mag = np.array(totalmag) dmag = np.array(totaldmag) filts = np.array(totalfilts) drng = max(t) - min(t) print("drng", drng) model = LombScargleMultiband(Nterms_band=n_band, Nterms_base=n_base, fit_period=True) #model = LombScargleMultibandFast(Nterms=2, fit_period = True) #this is not working in parallel for some reason model.optimizer.period_range = (0.2, drng) model.fit(t, mag, dmag, filts) LSM = model.best_period print('LSM running') return_dict[j] = return_dict[j] + [LSM] #n_totalrun += 1 print('LSM in return_dict') return_dict[j] = return_dict[j] + [delta_mag] else: return_dict[j] = return_dict[j] + [-999.] return_dict[j] = return_dict[j] + [-999.]
def run_ellc_gatspy(self, j): #this is the general simulation - ellc light curves and gatspy periodograms EB = self.return_dict[j] #for the multiband gatspy fit allObsDates = np.array([]) allAppMagObs = np.array([]) allAppMagObsErr = np.array([]) allObsFilters = np.array([]) if (self.verbose): print("in run_ellc_gatspy") for i, filt in enumerate(self.filters): #observe the EB (get dates, create the light curve for this filter) EB.observe(filt) EB.LSS[filt] = -999. if (EB.obsDates[filt][0] != None and min(EB.appMagObs[filt]) > 0): #run gatspy for this filter drng = max(EB.obsDates[filt]) - min(EB.obsDates[filt]) #print("filter, nobs", filt, len(EB.obsDates[filt])) if (self.useFast and len(EB.obsDates[filt]) > 50): model = LombScargleFast(fit_period=True) else: model = LombScargle(fit_period=True) model.optimizer.period_range = (0.2, drng) model.fit(EB.obsDates[filt], EB.appMagObs[filt], EB.appMagObsErr[filt]) EB.LSS[filt] = model.best_period EB.LSSmodel[filt] = model EB.maxDeltaMag = max(EB.deltaMag[filt], EB.maxDeltaMag) #to use for the multiband fit allObsDates = np.append(allObsDates, EB.obsDates[filt]) allAppMagObs = np.append(allAppMagObs, EB.appMagObs[filt]) allAppMagObsErr = np.append(allAppMagObsErr, EB.appMagObsErr[filt]) allObsFilters = np.append( allObsFilters, np.full(len(EB.obsDates[filt]), filt)) if (self.verbose): print(j, 'filter = ', filt) print(j, 'obsDates = ', EB.obsDates[filt][0:10]) print(j, 'appMagObs = ', EB.appMagObs[filt][0:10]) print(j, 'delta_mag = ', EB.deltaMag[filt]) print(j, 'LSS = ', EB.LSS[filt]) if (len(allObsDates) > 0 and self.doLSM): drng = max(allObsDates) - min(allObsDates) if (self.useFast and len(allObsDates) > 50 * len(self.filters)): model = LombScargleMultibandFast(fit_period=True) else: model = LombScargleMultiband(Nterms_band=self.n_band, Nterms_base=self.n_base, fit_period=True) model.optimizer.period_range = (0.2, drng) model.fit(allObsDates, allAppMagObs, allAppMagObsErr, allObsFilters) EB.LSM = model.best_period EB.LSMmodel = model if (self.verbose): print(j, 'LSM =', EB.LSM) #not sure if I need to do this... self.return_dict[j] = EB
yerr=data['flux_bgsub_err'][flg0] / (1e-15), marker='.', linestyle='none') plt.xlabel('GALEX time (sec - ' + str(t0k) + ')') # plt.ylabel('NUV Flux') plt.ylabel('NUV Flux \n' r'(x10$^{-15}$ erg s$^{-1}$ cm$^{-2}$ ${\rm\AA}^{-1}$)') plt.title('Flags = 0') minper = 10 # my windowing maxper = 200000 nper = 1000 pgram = LombScargleFast(fit_offset=False) pgram.optimizer.set(period_range=(minper, maxper)) pgram = pgram.fit(time_big - min(time_big), flux_big - np.nanmedian(flux_big)) df = (1. / minper - 1. / maxper) / nper f0 = 1. / maxper pwr = pgram.score_frequency_grid(f0, df, nper) freq = f0 + df * np.arange(nper) per = 1. / freq ## plt.figure() plt.plot(per, pwr, lw=0.75) plt.xlabel('Period (seconds)') plt.ylabel('L-S Power') plt.xscale('log')