Ejemplo n.º 1
0
def make_plot(days_ago, dates, mag):
    print('Making plot...')
    time_span = np.max(dates) - np.min(dates)
    flatten_lc, trend_lc = flatten(
        days_ago,
        mag,
        method='lowess',
        window_length=time_span/3,
        return_trend=True,
        )
    plt.scatter(days_ago, mag, s=5, color='blue', alpha=0.5)

    plt.scatter(days_ago1, all_mags1, s=10, color='black', alpha=0.8, marker="x")
    plt.xlabel('Days before today')
    plt.ylabel('Visual magnitude')
    #mid = biweight_location(mag)
    mid = 1.10
    plt.ylim(mid-1, mid+1)
    plt.xlim(-1, 20)
    plt.plot(days_ago, trend_lc, color='red', linewidth=1)
    plt.gca().invert_yaxis()
    plt.gca().invert_xaxis()
    date_text = datetime.datetime.now().strftime("%d %b %Y")
    data_last24hrs = np.where(days_ago<1)
    mean_last24hrs = biweight_location(mag[data_last24hrs])
    lumi = str(format(mean_last24hrs, '.2f'))
    plt.text(19.5, mid+1-0.25, "AAVSO observations visual (by-eye) in blue", color='blue')
    plt.text(19.5, mid+1-0.15, "AAVSO observations from CCDs in black", color='black')
    plt.text(19.5, mid+1-0.05, "LOESS trend in red", color='red')
    plt.text(19.5, mid-1+0.1, '#Betelgeuse brightness ' + lumi + " mag on " + date_text + " by @betelbot")
    plt.savefig(plot_file, bbox_inches='tight', dpi=300)
    print('Done.')
Ejemplo n.º 2
0
 def flatten_gp(self, flatten_input):
     flatten_lc, trend = wotan.flatten(flatten_input.time, flatten_input.flux, method="gp", kernel='matern',
                                            kernel_size=flatten_input.wl, return_trend=True, break_tolerance=0.5)
     flatten_lc = sigma_clip(flatten_lc, sigma_lower=20, sigma_upper=3)
     bin_centers_i, bin_means_i, bin_width_i, bin_edges_i, bin_stds_i = \
         self.__compute_flatten_stats(flatten_input.time, flatten_lc, flatten_input.bin_minutes)
     return flatten_lc, trend, bin_centers_i, bin_means_i, flatten_input.wl
Ejemplo n.º 3
0
 def flatten_bw(self, flatten_input):
     flatten_lc, trend = wotan.flatten(flatten_input.time, flatten_input.flux, window_length=flatten_input.wl,
                                 return_trend=True, method="biweight", break_tolerance=0.5)
     flatten_lc = sigma_clip(flatten_lc, sigma_lower=20, sigma_upper=3)
     bin_centers_i, bin_means_i, bin_width_i, bin_edges_i, bin_stds_i = \
         self.__compute_flatten_stats(flatten_input.time, flatten_lc, flatten_input.bin_minutes)
     return flatten_lc, trend, bin_centers_i, bin_means_i, flatten_input.wl
Ejemplo n.º 4
0
def SNR(alltimes, lc, dip, x0):
	
	'''
	Calculates SNR for event

	Takes in:
		alltimes: array - Time series
		lc: array - light curve
		dip: float - depth of transit
		x0: tuple - best fit parameters
	Returns:
		SNR: float - Signal to noise ratio

	'''

	(tmid, dur) = x0[:2]

	lc = np.array(lc)

	if np.all(np.isnan(lc)):
		return np.nan

	#To find SNR - take detrended curve to find overall stddev - wotan preserves SNR (I think ...)

	lc_flat = flatten(alltimes, lc, window_length = 0.5, method = 'biweight', return_trend = False)

	masked_lc = lc_flat
	masked_lc[int(tmid - dur*0.5):int(tmid+dur*0.5)]=np.nan

	sigma_oot = np.nanstd(masked_lc)




	return dip/sigma_oot
Ejemplo n.º 5
0
 def __detrend_by_period(self, method, time, flux, period_window):
     if method == 'gp':
         flatten_lc, lc_trend = flatten(time,
                                        flux,
                                        method=method,
                                        kernel='matern',
                                        kernel_size=period_window,
                                        return_trend=True,
                                        break_tolerance=0.5)
     else:
         flatten_lc, lc_trend = flatten(time,
                                        flux,
                                        window_length=period_window,
                                        return_trend=True,
                                        method=method,
                                        break_tolerance=0.5)
     return flatten_lc, lc_trend
Ejemplo n.º 6
0
    def get_numax(self):
        # use 2d ACF to get a rough estimation on numax
        freqRanges = np.logspace(
            min(np.log10(15.), np.log10(np.min(self.freq))),
            np.log10(np.max(self.freq)), 250)
        # freqRanges = np.linspace(15., np.max(freq), 200.)
        freqCenters = (freqRanges[1:] + freqRanges[:-1]) / 2.
        spacings = np.diff(freqRanges)
        widths = 0.263 * freqCenters**0.772 * 4.

        # # crude background estimation

        cacf = np.zeros(len(spacings))
        acf2d = np.zeros([140, len(spacings)])
        for isp, width in enumerate(widths):
            idx = (self.freq >= freqRanges[isp]) & (self.freq <=
                                                    freqRanges[isp] + width)

            if np.sum(idx) > 100:
                # powerbg = percentile_filter(self.power[idx], 15, size=int(width/np.median(np.diff(self.freq[idx]))))
                # powerbg = np.percentile(self.power[idx], 20)
                lag, rho = a_correlate(
                    self.freq[idx],
                    self.power[idx])  # return the acf at this freqRange
                acf = np.interp(
                    np.arange(30, 170) / 200 * np.max(lag), lag,
                    rho)  # switch to the scale of width
                acf2d[:, isp] = np.abs(detrend(acf))  # store the 2D acf
                cacf[isp] = np.sum(np.abs(
                    detrend(acf)))  # store the max acf power (collapsed acf)
            else:
                acf2d[:, isp] = 0.
                cacf[isp] = np.nan

        # detrend the data to find the peak
        idx = np.isfinite(cacf)
        cacfDetrend = np.zeros(len(cacf))
        cacfDetrend[idx] = flatten(np.arange(np.sum(idx)),
                                   cacf[idx],
                                   method='biweight',
                                   window_length=50,
                                   edge_cutoff=10)

        # The highest value of the cacf (smoothed) corresponds to numax
        cacf_numax = freqCenters[np.nanargmax(cacfDetrend)]

        # create and return the object containing the result
        self.numax_diagnostics = {
            'cacf': cacf,
            'acf2d': acf2d,
            'freqCenters': freqCenters,
            'spacings': spacings,
            'widths': widths,
            'freqRanges': freqRanges,
            'cacfDetrend': cacfDetrend,
            'cacf_numax': cacf_numax
        }
        return self.numax_diagnostics
Ejemplo n.º 7
0
 def get_flat_lc(
     self,
     lc=None,
     period=None,
     epoch=None,
     duration=None,
     window_length=None,
     method="biweight",
     sigma_upper=None,
     sigma_lower=None,
     return_trend=False,
 ):
     """
     """
     lc = self.lc if lc is None else lc
     period = self.period if period is None else period
     epoch = self.epoch if epoch is None else epoch
     duration = self.duration if duration is None else duration
     duration_hours = duration * 24
     if duration_hours < 1:
         raise ValueError("Duration should be in hours.")
     if window_length is None:
         window_length = 0.5 if duration is None else duration * 3
     if self.verbose:
         print(
             f"Using {method} filter with window_length={window_length:.2f} day"
         )
     if (period is not None) & (epoch is not None) & (duration is not None):
         tmask = get_transit_mask(lc.time,
                                  period=period,
                                  t0=epoch,
                                  dur=duration_hours / 24)
     else:
         tmask = np.zeros_like(lc.time, dtype=bool)
     # dummy holder
     flat, trend = lc.flatten(return_trend=True)
     # flatten using wotan
     wflat, wtrend = flatten(
         lc.time,
         lc.flux,
         method=method,
         window_length=window_length,
         mask=tmask,
         return_trend=True,
     )
     # overwrite
     flat.flux = wflat
     trend.flux = wtrend
     # clean lc
     sigma_upper = 5 if sigma_upper is None else sigma_upper
     sigma_lower = 10 if sigma_lower is None else sigma_lower
     flat = (
         flat.remove_nans()
     )  # .remove_outliers(sigma_upper=sigma_upper, sigma_lower=sigma_lower)
     if return_trend:
         return flat, trend
     else:
         return flat
Ejemplo n.º 8
0
 def __detrend_by_period(self, lc, period_window, detrend_method):
     if detrend_method == 'gp':
         flatten_lc, lc_trend = flatten(lc.time.value,
                                        lc.flux.value,
                                        method=detrend_method,
                                        kernel='matern',
                                        kernel_size=period_window,
                                        return_trend=True,
                                        break_tolerance=0.5)
     else:
         flatten_lc, lc_trend = flatten(lc.time.value,
                                        lc.flux.value,
                                        window_length=period_window,
                                        return_trend=True,
                                        method=detrend_method,
                                        break_tolerance=0.5)
     flatten_lc = sigma_clip(flatten_lc, sigma_lower=20, sigma_upper=3)
     return flatten_lc, lc_trend
Ejemplo n.º 9
0
 def __tls_search(self, time, flux, rstar, rstar_min, rstar_max, mass,
                  mstar_min, mstar_max, ab, intransit, epoch, period,
                  min_period, max_period, min_snr, cores, transit_template,
                  ws, transits_min_count, run_limit):
     snr = 1e12
     found_signal = False
     time = time[~intransit]
     flux = flux[~intransit]
     time, flux = cleaned_array(time, flux)
     run = 0
     if ws > 0:
         flux = wotan.flatten(time,
                              flux,
                              window_length=ws,
                              return_trend=False,
                              method='biweight',
                              break_tolerance=0.5)
     while snr >= min_snr and not found_signal and (run_limit > 0
                                                    and run < run_limit):
         model = transitleastsquares(time, flux)
         # R_starx = rstar / u.R_sun
         results = model.power(
             u=ab,
             R_star=rstar,  # rstar/u.R_sun,
             R_star_min=rstar_min,  # rstar_min/u.R_sun,
             R_star_max=rstar_max,  # rstar_max/u.R_sun,
             M_star=mass,  # mstar/u.M_sun,
             M_star_min=mstar_min,  # mstar_min/u.M_sun,
             M_star_max=mstar_max,  # mstar_max/u.M_sun,
             period_min=min_period,
             period_max=max_period,
             n_transits_min=transits_min_count,
             show_progress_bar=True,
             use_threads=cores,
             transit_template=transit_template)
         snr = results.snr
         if results.snr >= min_snr:
             intransit_result = transit_mask(time, results.period,
                                             2 * results.duration,
                                             results.T0)
             time = time[~intransit_result]
             flux = flux[~intransit_result]
             time, flux = cleaned_array(time, flux)
             right_period = self.__is_multiple_of(results.period,
                                                  period / 2.)
             right_epoch = False
             for tt in results.transit_times:
                 for i in range(-5, 5):
                     right_epoch = right_epoch or (
                         np.abs(tt - epoch + i * period) < (1. / 24.))
             #            right_depth   = (np.abs(np.sqrt(1.-results.depth)*rstar - rplanet)/rplanet < 0.05) #check if the depth matches
             if right_period and right_epoch:
                 found_signal = True
                 break
         run = run + 1
     return found_signal, results.snr, results.SDE, run
Ejemplo n.º 10
0
 def __tls_search(self, time, flux, rstar, rstar_min, rstar_max, mass,
                  mstar_min, mstar_max, ab, intransit, epoch, period,
                  min_period, max_period, min_snr, cores, transit_template):
     SNR = 1e12
     FOUND_SIGNAL = False
     time = time[~intransit]
     flux = flux[~intransit]
     time, flux = cleaned_array(time, flux)
     run = 0
     flux = wotan.flatten(time,
                          flux,
                          window_length=0.5,
                          return_trend=False,
                          method='biweight',
                          break_tolerance=0.5)
     #::: search for the rest
     while (SNR >= min_snr) and (not FOUND_SIGNAL):
         model = transitleastsquares(time, flux)
         # R_starx = rstar / u.R_sun
         results = model.power(
             u=ab,
             R_star=rstar,  # rstar/u.R_sun,
             R_star_min=rstar_min,  # rstar_min/u.R_sun,
             R_star_max=rstar_max,  # rstar_max/u.R_sun,
             M_star=mass,  # mstar/u.M_sun,
             M_star_min=mstar_min,  # mstar_min/u.M_sun,
             M_star_max=mstar_max,  # mstar_max/u.M_sun,
             period_min=min_period,
             period_max=max_period,
             n_transits_min=2,
             show_progress_bar=False,
             use_threads=cores,
             transit_template=transit_template)
         SNR = results.snr
         if results.snr >= min_snr:
             intransit_result = transit_mask(time, results.period,
                                             2 * results.duration,
                                             results.T0)
             time = time[~intransit_result]
             flux = flux[~intransit_result]
             time, flux = cleaned_array(time, flux)
             right_period = self.__is_multiple_of(results.period,
                                                  period / 2.)
             right_epoch = False
             for tt in results.transit_times:
                 for i in range(-5, 5):
                     right_epoch = right_epoch or (
                         np.abs(tt - epoch + i * period) < (1. / 24.)
                     )  # check if any epochs matches to within 1 hour
             #            right_depth   = (np.abs(np.sqrt(1.-results.depth)*rstar - rplanet)/rplanet < 0.05) #check if the depth matches
             if right_period and right_epoch:
                 FOUND_SIGNAL = True
                 break
         run = run + 1
     return FOUND_SIGNAL, results.snr, results.SDE, run
Ejemplo n.º 11
0
def _get_flat_lc(
    self,
    lc,
    period=None,
    epoch=None,
    duration=None,
    window_length=None,
    method="biweight",
    return_trend=False,
    **wotan_kwargs,
):
    """
    TODO: migrate self in class method;
    See plot_hrd in cluster.py
    """
    period = self.toi_period if period is None else period
    epoch = self.toi_epoch - TESS_TIME_OFFSET if epoch is None else epoch
    duration = self.toi_duration if duration is None else duration
    if duration is not None:
        if duration < 1:
            print("Duration should be in hours.")
    if window_length is None:
        window_length = 0.5 if duration is None else duration / 24 * 3
    if self.verbose:
        print(
            f"Using {method} filter with window_length={window_length:.2f} day."
        )
    if (period is not None) & (epoch is not None) & (duration is not None):
        tmask = get_transit_mask(lc.time,
                                 period=period,
                                 t0=epoch,
                                 dur=duration / 24)
    else:
        tmask = np.zeros_like(lc.time, dtype=bool)
    # dummy holder
    flat, trend = lc.flatten(return_trend=True)
    # flatten using wotan
    # import pdb; pdb.set_trace()
    wflat, wtrend = flatten(
        lc.time,
        lc.flux,
        method=method,
        mask=tmask,
        window_length=window_length,
        return_trend=True,
        **wotan_kwargs,
    )
    # overwrite
    flat.flux = wflat
    trend.flux = wtrend
    if return_trend:
        return flat, trend
    else:
        return flat
Ejemplo n.º 12
0
def eigvec_smooth_fn(time, eigenvec):

    _, smoothed = flatten(time - np.nanmin(time),
                          1 + eigenvec,
                          break_tolerance=0.5,
                          method='biweight',
                          window_length=1,
                          cval=6,
                          edge_cutoff=0,
                          return_trend=True)

    return smoothed
Ejemplo n.º 13
0
def make_plot(days_ago, dates, mag):
    print('Making plot...')
    time_span = np.max(dates) - np.min(dates)
    flatten_lc, trend_lc = flatten(
        days_ago,
        mag,
        method='lowess',
        window_length=time_span / 5,
        return_trend=True,
    )
    #mpl.rcParams['font.sans-serif']=['Times New Roman']   #指定默认字体 SimHei为黑体
    mpl.rcParams['font.sans-serif'] = ['SimHei']
    mpl.rcParams['axes.unicode_minus'] = False  #用来正常显示负号
    #fontcn = {'family': 'Droid Sans Fallback'} # 1pt = 4/3px
    fontcn = {'family': 'SimHei'}  # 1pt = 4/3px
    fonten = {'family': 'Times New Roman'}
    plt.scatter(days_ago, mag, s=5, color='blue', alpha=0.5)
    plt.scatter(days_ago1,
                all_mags1,
                s=10,
                color='black',
                alpha=0.8,
                marker="x")
    plt.xlabel(u'从今天往回数的天数', fontdict=fontcn)
    #plt.xlabel('从今天往回数的天数')
    plt.ylabel(u'视星等', fontdict=fontcn)
    mid = 0.6
    plt.ylim(mid - 1, mid + 1)
    plt.xlim(-1, 20)
    plt.plot(days_ago, trend_lc, color='red', linewidth=1)
    plt.gca().invert_yaxis()
    plt.gca().invert_xaxis()
    date_text = datetime.datetime.now().strftime("%Y-%m-%d")
    data_last24hrs = np.where(days_ago < 1)
    mean_last24hrs = biweight_location(mag[data_last24hrs])
    lumi = str(format(mean_last24hrs, '.2f'))
    plt.text(19.5, mid + 1 - 0.25, u"裸眼 ", color='blue', fontdict=fontcn)
    plt.text(18, mid + 1 - 0.25, u"观测星等 蓝色", color='blue', fontdict=fontcn)
    plt.text(14, mid + 1 - 0.25, u"○", color='blue', fontdict=fonten)
    plt.text(19.5, mid + 1 - 0.15, u"CCD ", color='black', fontdict=fonten)
    plt.text(18, mid + 1 - 0.15, u"观测星等 黑色", color='black', fontdict=fontcn)
    plt.text(14, mid + 1 - 0.15, u"×", color='black', fontdict=fonten)
    plt.text(19.5, mid + 1 - 0.05, u"局部加权拟合 红色线", color='red', fontdict=fontcn)
    plt.text(7.5, mid - 1 + 0.1, u'目前参宿四的星等为 ', fontdict=fontcn)
    plt.text(2, mid - 1 + 0.1, lumi, fontdict=fonten)
    plt.text(7.5, mid - 1 + 0.2, u"由 天文通 译制于", fontdict=fontcn)
    plt.text(3, mid - 1 + 0.2, date_text, fontdict=fonten)
    plt.savefig(plot_file, bbox_inches='tight', dpi=300)
    print('Done.')
Ejemplo n.º 14
0
 def __clean(self, lc, detrend_period, detrend_period_method,
             custom_clean_algorithm):
     clean_flux = lc.flux.value
     time = lc.time.value
     if custom_clean_algorithm is not None:
         clean_flux = custom_clean_algorithm.clean(time, clean_flux)
     elif detrend_period:
         periodogram = lc.to_periodogram(minimum_period=0.05,
                                         maximum_period=15,
                                         oversample_factor=10)
         ws = self.__calculate_max_significant_period(lc, periodogram)
         clean_flux = wotan.flatten(time,
                                    clean_flux,
                                    window_length=ws,
                                    return_trend=False,
                                    method=detrend_period_method,
                                    break_tolerance=0.5)
     return clean_flux
Ejemplo n.º 15
0
def detrend_tessphot(x_obs, y_obs, y_err):

    from wotan import flatten

    flat_flux, trend_flux = flatten(x_obs,
                                    y_obs,
                                    method='hspline',
                                    window_length=0.3,
                                    break_tolerance=0.4,
                                    return_trend=True)

    # flat_flux, trend_flux = flatten(time, flux, method='pspline',
    #                                 break_tolerance=0.4, return_trend=True)
    # flat_flux, trend_flux = flatten(time, flux, method='biweight',
    #                                 window_length=0.3, edge_cutoff=0.5,
    #                                 break_tolerance=0.4, return_trend=True,
    #                                 cval=2.0)

    return flat_flux, trend_flux
Ejemplo n.º 16
0
def wotan_detrend(time,
                  flux,
                  window_length=0.1,
                  method='biweight',
                  edge_cutoff=0.5,
                  break_tolerance=0.5,
                  cval=5.0):
    """
    Detrends the light curve using methods in wotan.flatten().

    Parameters
    ----------
    time : np.ndarray
    flux : np.ndarray
    window_length : str, optional                                                                 
         The window length used for the robust estimator. Default = 0.1.
         For the biweight filter, window_length is given in unit days.
         For the savgol filter, window_length is given in unit cadences.
    method : str, optional.
         The type of detrending to use on the light curve. Default is 'biweight'.
    edge_cutoff: float, optional
         Trims data near the edges of the light curve. Default = 0.5. Only available
         for the biweight detrending method.
    break_tolerance : float, optional
         Breaks the light curve into segments to help alleviate gap issues. 
         Default = 0.5.
    cval : float, optional
         Tuning parameter for robust M-estimators. Defined as multiples in units
         of median absolute deviation from central location. Default = 5.0.
         Only available for the biweight detrending method.

    Returns
    ----------
    detrend : detranded flux
    """
    detrend = wotan.flatten(time,
                            flux,
                            window_length=window_length,
                            method=method,
                            edge_cutoff=edge_cutoff,
                            break_tolerance=break_tolerance,
                            cval=cval)
    return detrend
Ejemplo n.º 17
0
def fast_slide_clip(time, flux, window_length=1, low=5, high=5):
    """
    A much faster alternative to Wotan's build-in slide clip

    Returns
    -------
    Clipped flux (outliers replaced with NaN)
    """
    flux2 = 1. * flux
    flux_flat = flatten(time,
                        flux,
                        method='biweight',
                        window_length=window_length)
    flux_flat = sigma_clip(np.ma.masked_invalid(flux_flat),
                           sigma_lower=low,
                           sigma_upper=high)  #astropy wants masked arrays
    flux2[
        flux_flat.
        mask] = np.nan  #use NaN instead of masked arrays, because masked arrays drive me crazy
    return flux2
Ejemplo n.º 18
0
def test_wotan_fake_data(t0):
    # t0: time system offset

    delta_t = 0.5/24 # TESS FFI cadence
    time = t0+np.arange(0, 28.5, delta_t)
    rotation_period = 2
    rotation_semiamplitude = 10 # units: part per thousdand. 10 <-> 1%
    flux = 1 + ((
        30*np.sin(2*np.pi*(time-t0)/rotation_period)
        + (time-t0) / 10
        + (time-t0)**1.5 / 100) / 1000
    )

    noise = np.random.normal(0, 0.0001, len(time))

    flux += noise
    for i in range(len(time)):
        if i % 75 == 0:
            flux[i:i+5] -= 5e-3  # Add some transits
            flux[i+50:i+52] += 5e-3  # and flares
    flux[300:400] = np.nan  # and a gap

    flatten_lc, trend_lc = flatten(
        time,                 # Array of time values
        flux,                 # Array of flux values
        method='biweight',
        window_length=0.5,    # The length of the filter window in units of ``time``
        edge_cutoff=0.5,      # length (in units of time) to be cut off each edge.
        break_tolerance=0.5,  # Split into segments at breaks longer than that
        return_trend=True,    # Return trend and flattened light curve
        cval=6              # Tuning parameter for the robust estimators
        )

    f,ax = plt.subplots(nrows=2, ncols=1, figsize=(16,8))
    ax[0].scatter(time, flux, color='black', s=3, zorder=5)
    ax[0].plot(time, trend_lc, color='red', lw=1, zorder=3)

    ax[1].scatter(time, flatten_lc, s=1, color='black')
    f.savefig('test_wotan_plots/test_wotan_fake_data_t0_{}.png'.format(t0), bbox_inches='tight')
Ejemplo n.º 19
0
def slide_clip(time, y, window_length=1, low=4, high=4, return_mask=False):
    """
    Slide clip outliers from a non-stationary time series;
    a much faster alternative to Wotan's built-in slide clip.

    Parameters
    ----------
    time : array of flaot
        Time stamps.
    y : array of float
        Any data corresponding to the time stamps.\
    window_length : float, optional
        The length of the sliding window (in time's units). The default is 1.
    low : float, optional
        The lower sigma. The default is 5.
    high : float, optional
        The upper sigma. The default is 5.
    return_mask : bool, optional
        Return the masks or only the clipped time series. The default is False.

    Returns
    -------
    Clipped y (outliers replaced with NaN).
    """
    y_flat = flatten(time, y, method='biweight', window_length=window_length)
    y2, mask, mask_upper, mask_lower = sigma_clip(time,
                                                  y_flat,
                                                  low=low,
                                                  high=high,
                                                  return_mask=True)
    y3 = 1 * y
    y3[mask] = np.nan

    if not return_mask:
        return y3

    else:
        return y3, mask, mask_upper, mask_lower
Ejemplo n.º 20
0
def analyse(det_met, time_i, flatten_i, n_tra, ab, mass, mass_min, mass_max,
            radius, radius_min, radius_max, id_run):
    # ---------------------------------------------------------------------------------------------------------------------------------------------------------
    # Detrending of the data using WOTAN
    # ---------------------------------------------------------------------------------------------------------------------------------------------------------
    # By default is used a 'biweight' method.
    # It will detrend the lightcurve 'N_detrends' independent times
    from wotan import flatten

    if det_met == 2:
        wl_min = 1
        wl_max = 12
    else:
        tdur = t14(
            R_s=radius, M_s=mass, P=P_protec, small_planet=True
        )  # we define the typical duration of a small planet in this star
        wl_min = 3 * tdur  # minimum transit duration
        wl_max = 20 * tdur  # maximum transit duration

    wl_step = (wl_max - wl_min) / N_detrends
    wl = np.arange(
        wl_min, wl_max,
        wl_step)  # we define all the posibles window_length that we apply
    global_flatten_lc = np.zeros((len(wl), len(flatten_i)))
    global_trend_lc = np.zeros((len(wl), len(flatten_i)))

    for i in range(0, len(wl)):
        if det_met == 2:
            flatten_lc, trend_lc = flatten(time_i,
                                           flatten_i,
                                           method='gp',
                                           kernel='matern',
                                           kernel_size=wl[i],
                                           return_trend=True,
                                           break_tolerance=0.5)
        else:
            flatten_lc, trend_lc = flatten(time_i,
                                           flatten_i,
                                           window_length=wl[i],
                                           return_trend=True,
                                           method='biweight',
                                           break_tolerance=0.5)
        global_flatten_lc[i] = flatten_lc
        global_trend_lc[i] = trend_lc

    ## save in the log file all the information concerning the detrendins applied
    warnings.filterwarnings("ignore")

    global_final = np.zeros((len(wl), len(flatten_i)))

    logprint('\n MODELS IN THE DETRENDING - Run ' + str(id_run))
    logprint('========================================\n')

    if det_met == 2:
        det_model = 'kernel_size:'
    else:
        det_model = 'window_size:'

    bins = len(time_i) * 2 / minutes
    bin_means, bin_edges, binnumber = stats.binned_statistic(time_i,
                                                             flatten_i,
                                                             statistic='mean',
                                                             bins=bins)
    bin_stds, _, _ = stats.binned_statistic(time_i,
                                            flatten_i,
                                            statistic='std',
                                            bins=bins)
    bin_width = (bin_edges[1] - bin_edges[0])
    bin_centers = bin_edges[1:] - bin_width / 2

    logprint('PDCSAP_FLUX_' + str(id_run), '\t ', ' ------ ', '\t', '------',
             '\t', '\t', 'RMS (ppm):',
             np.std(flatten_i) * 1e6, '\t', 'RMS_10min (ppm):',
             np.std(bin_means[~np.isnan(bin_means)]) * 1e6)
    for i in range(len(wl)):
        flatten = sigma_clip(global_flatten_lc[i],
                             sigma_lower=20,
                             sigma_upper=3)
        global_final[i] = flatten
        bins_i = len(time_i) * 2 / minutes
        bin_means_i, bin_edges_i, binnumber_i = stats.binned_statistic(
            time_i, flatten, statistic='mean', bins=bins_i)
        bin_stds_i, _, _ = stats.binned_statistic(time_i,
                                                  flatten,
                                                  statistic='std',
                                                  bins=bins_i)
        bin_width_i = (bin_edges_i[1] - bin_edges_i[0])
        bin_centers_i = bin_edges_i[1:] - bin_width_i / 2
        logprint('flatten_lc%s' % i, '\t ', 'trend_lc%s' % i, '\t', det_model,
                 format(wl[i], '0.4f'), '\t', 'RMS (ppm):',
                 np.std(flatten) * 1e6, '\t', 'RMS_10min (ppm):',
                 np.std(bin_means_i[~np.isnan(bin_means_i)]) * 1e6)

    ## save in a plot all the detrendings and all the data to inspect visually.
    cases = np.zeros((len(wl), 1))
    for i in range(len(wl)):
        cases[i] = wl[i]

    figsize = (8, 8)  #x,y
    cols = 3
    rows = len(cases) // cols

    shift = 2 * (1.0 - (np.min(flatten_i))
                 )  #shift in the between the raw and detrended data
    ylim_max = 1.0 + 3 * (np.max(flatten_i) - 1.0
                          )  #shift in the between the raw and detrended data
    ylim_min = 1.0 - 2.0 * shift  #shift in the between the raw and detrended data

    fig1, axs = plt.subplots(rows,
                             cols,
                             figsize=figsize,
                             constrained_layout=True)
    axs = trim_axs(axs, len(cases))
    for ax, case in zip(axs, cases):
        if det_met == 2:
            ax.set_title('ks=%s' % str(np.around(case, decimals=4)))
        else:
            ax.set_title('ws=%s' % str(np.around(case, decimals=4)))

        bins_i = len(time_i) * 2 / minutes
        bin_means_i, bin_edges_i, binnumber_i = stats.binned_statistic(
            time_i,
            global_final[np.nonzero(cases == case)[0][0]],
            statistic='mean',
            bins=bins_i)
        bin_stds_i, _, _ = stats.binned_statistic(
            time_i,
            global_final[np.nonzero(cases == case)[0][0]],
            statistic='std',
            bins=bins_i)
        bin_width_i = (bin_edges_i[1] - bin_edges_i[0])
        bin_centers_i = bin_edges_i[1:] - bin_width_i / 2

        ax.plot(time_i,
                flatten_i,
                linewidth=0.05,
                color='black',
                alpha=0.75,
                rasterized=True)
        ax.plot(time_i,
                global_trend_lc[np.nonzero(cases == case)[0][0]],
                linewidth=1,
                color='orange',
                alpha=1.0)
        ax.plot(time_i,
                global_final[np.nonzero(cases == case)[0][0]] - shift,
                linewidth=0.05,
                color='teal',
                alpha=0.75,
                rasterized=True)
        ax.plot(bin_centers_i,
                bin_means_i - shift,
                marker='.',
                markersize=2,
                color='firebrick',
                alpha=0.5,
                linestyle='none',
                rasterized=True)

        ax.set_ylim(ylim_min, ylim_max)
        plt.savefig('Detrends_' + 'run_' + str(id_run) + '_TIC' + str(TIC_ID) +
                    '.png',
                    dpi=200)

    # ---------------------------------------------------------------------------------------------------------------------------------------------------------
    # Search of signals in the raw data
    # ---------------------------------------------------------------------------------------------------------------------------------------------------------
    logprint('\n SEARCH OF SIGNALS - Run', id_run)
    logprint('=================================\n')

    logprint('PDCSAP_FLUX_' + str(id_run), '\t', 'Period', '\t', 'Per_err',
             '\t', 'N.Tran', '\t', 'Mean Depth(ppt)', '\t', 'T. dur(min)',
             '\t', 'T0', '\t', 'SNR', '\t', 'SDE', '\t', 'FAP\n')
    model = transitleastsquares(time_i, flatten_i)
    results_pdcsap = model.power(u=ab,
                                 M_star=mass,
                                 M_star_min=mass_min,
                                 M_star_max=mass_max,
                                 R_star=radius,
                                 R_star_min=radius_min,
                                 R_star_max=radius_max,
                                 period_min=Pmin,
                                 period_max=Pmax,
                                 n_transits_min=n_tra,
                                 show_progress_bar=False)
    x = []

    if results_pdcsap.T0 != 0:
        for j in range(0, len(results_pdcsap.transit_depths)):
            # print (results.transit_depths[i])
            x = np.append(x, results_pdcsap.transit_depths[j])
            x = x[~np.isnan(x)]
            depth = (1. - np.mean(x)) * 100 / 0.1  #we change to ppt units
    else:
        depth = results_pdcsap.transit_depths

    logprint('-----', '\t ', format(results_pdcsap.period, '.5f'), '\t ',
             format(results_pdcsap.period_uncertainty, '.6f'),
             '\t ', results_pdcsap.distinct_transit_count, '\t',
             format(depth, '.3f'), '\t',
             format(results_pdcsap.duration * 24 * 60,
                    '.1f'), '\t', results_pdcsap.T0, '\t ',
             format(results_pdcsap.snr, '.3f'), '\t ',
             format(results_pdcsap.SDE, '.3f'), '\t ', results_pdcsap.FAP)
    logprint('\n')

    # ---------------------------------------------------------------------------------------------------------------------------------------------------------
    # Saving a plot of the best signal from raw data
    # ---------------------------------------------------------------------------------------------------------------------------------------------------------
    fig = save_plot(time_i, global_final, results_pdcsap, i)

    fig.suptitle('PDCSAP_FLUX_' + str(id_run) + ' ## SNR:' +
                 str(format(results_pdcsap.snr, '.3f')) + ' ## SDE:' +
                 str(format(results_pdcsap.SDE, '.3f')) + ' ## FAP:' +
                 str(results_pdcsap.FAP))
    plt.savefig('Run_' + str(id_run) + '_PDCSAP-FLUX_' + 'TIC' + str(TIC_ID) +
                '.png',
                bbox_inches='tight',
                dpi=200)

    # ---------------------------------------------------------------------------------------------------------------------------------------------------------
    # Search of signals in the detrended data
    # ---------------------------------------------------------------------------------------------------------------------------------------------------------
    if det_met == 2:
        logprint('Kernel_size', '\t', 'Period', '\t', 'Per_err', '\t',
                 'N.Tran', '\t', 'Mean Depth(ppt)', '\t', 'T. dur(min)', '\t',
                 'T0', '\t', 'SNR', '\t', 'SDE', '\t', 'FAP\n')
    else:
        logprint('Window_size', '\t', 'Period', '\t', 'Per_err', '\t',
                 'N.Tran', '\t', 'Mean Depth(ppt)', '\t', 'T. dur(min)', '\t',
                 'T0', '\t', 'SNR', '\t', 'SDE', '\t', 'FAP\n')
    SNR = np.zeros((len(wl), 1))
    SDE = np.zeros((len(wl), 1))
    FAP = np.zeros((len(wl), 1))
    periods = np.zeros((len(wl), 1))
    per_err = np.zeros((len(wl), 1))
    durations = np.zeros((len(wl), 1))
    tos = np.zeros((len(wl), 1))

    for i in range(len(wl)):
        print(i)
        model = transitleastsquares(time_i, global_final[i])
        results = model.power(u=ab,
                              M_star=mass,
                              M_star_min=mass_min,
                              M_star_max=mass_max,
                              R_star=radius,
                              R_star_min=radius_min,
                              R_star_max=radius_max,
                              period_min=Pmin,
                              period_max=Pmax,
                              n_transits_min=n_tra,
                              show_progress_bar=False)
        SNR[i] = results.snr
        SDE[i] = results.SDE
        FAP[i] = results.FAP
        periods[i] = results.period
        per_err[i] = results.period_uncertainty
        durations[i] = results.duration
        tos[i] = results.T0
        x = []
        if results.T0 != 0:
            for j in range(0, len(results.transit_depths)):
                # print (results.transit_depths[i])
                x = np.append(x, results.transit_depths[j])
                x = x[~np.isnan(x)]
                depth = (1. - np.mean(x)) * 100 / 0.1  #we change to ppt units
        else:
            depth = results.transit_depths
        logprint(format(wl[i], '.4f'), '\t ', format(results.period,
                                                     '.5f'), '\t ',
                 format(results.period_uncertainty,
                        '.6f'), '\t ', results.distinct_transit_count, '\t',
                 format(depth, '.3f'), '\t',
                 format(results.duration * 24 * 60, '.1f'), '\t', results.T0,
                 '\t ', format(results.snr, '.3f'), '\t ',
                 format(results.SDE, '.3f'), '\t ', results.FAP)

        # -----------------------------------------------------------------------------------------------------------------------------------------------------
        # Saving a plot of the best signal from detrended data
        # -----------------------------------------------------------------------------------------------------------------------------------------------------
        fig = save_plot(time_i, global_final, results, i)

        if det_met == 2:
            fig.suptitle('Run ' + str(id_run) + ' ## kernel_size:' +
                         str(format(wl[i], '.4f')) + ' ## SNR:' +
                         str(format(results.snr, '.3f')) + ' ## SDE:' +
                         str(format(results.SDE, '.3f')) + ' ## FAP:' +
                         str(results.FAP))
            #plt.savefig('TIC'+str(TIC_ID)+'_ks='+str(format(wl[i],'.4f'))+'_run_'+str(id_run)+'.png', bbox_inches='tight', dpi=200)
            plt.savefig('Run_' + str(id_run) + '_ks=' +
                        str(format(wl[i], '.4f')) + '_TIC' + str(TIC_ID) +
                        '.png',
                        bbox_inches='tight',
                        dpi=200)
        else:
            fig.suptitle('Run ' + str(id_run) + ' ## window_size:' +
                         str(format(wl[i], '.4f')) + ' ## SNR:' +
                         str(format(results.snr, '.3f')) + ' ## SDE:' +
                         str(format(results.SDE, '.3f')) + ' ## FAP:' +
                         str(results.FAP))
            #plt.savefig('TIC'+str(TIC_ID)+'_ws='+str(format(wl[i],'.4f'))+'_run_'+str(id_run)+'.png', bbox_inches='tight', dpi=200)
            plt.savefig('Run_' + str(id_run) + '_ws=' +
                        str(format(wl[i], '.4f')) + '_TIC' + str(TIC_ID) +
                        '.png',
                        bbox_inches='tight',
                        dpi=200)
    SNR = np.nan_to_num(SNR)
    a = np.nanargmax(SNR)  #check the maximum SRN

    if results_pdcsap.snr > SNR[a]:
        logprint('\nBest Signal -->', '\t', 'PDCSAP_FLUX', '\t', 'SNR:',
                 format(results_pdcsap.snr, '.3f'))

        if (
                results_pdcsap.snr > SNR_min
        ):  # and results_pdcsap.SDE > SDE_min and results_pdcsap.FAP < FAP_max):
            logprint(
                '\nBest Signal is good enough to keep searching. Going to the next run.'
            )
            key = 1
        else:
            logprint('\nBest Signal does not look very promising. End')
            key = 0
    else:
        if det_met == 2:
            logprint('\nBest Signal -->', '\t', 'flatten_lc' + str(a), '\t',
                     'kernel_size:', format(wl[a], '0.4f'), '\t', 'SNR:',
                     format(SNR[a][0], '.3f'))
        else:
            logprint('\nBest Signal -->', '\t', 'flatten_lc' + str(a), '\t',
                     'window_size:', format(wl[a], '0.4f'), '\t', 'SNR:',
                     format(SNR[a][0], '.3f'))

        if (SNR[a] > SNR_min):  #and SDE[a] > SDE_min and FAP[a] < FAP_max):
            logprint(
                '\nBest Signal is good enough to keep searching. Going to the next run.'
            )
            key = 1
        else:
            logprint('\nBest Signal does not look very promising. End')
            key = 0

    print("### SNR :", str(format(results.snr, '.3f')), "   SDE :",
          str(format(results.SDE, '.3f')), "   FAP :", str(results.FAP))

    return results_pdcsap, SNR, key, periods, durations, tos
Ejemplo n.º 21
0
            #ax.axvline(params.t0+2*params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            #ax.axvline(params.t0-params.per+lc_30min.time[index], ymin = 0.1, ymax = 0.2, lw=1, c = 'r')
            peak_cut_fig.savefig(save_path +
                                 "{} - Peak cut fig.png".format(target_ID))
            #peak_cut_fig.show()
            plt.close(peak_cut_fig)
        else:
            t_cut = lc_30min.time
            flux_cut = combined_flux
            print('else clause completed')

    #################################### Wotan ####################################
        if detrending == 'wotan':
            flatten_lc_before, trend_before = flatten(lc_30min.time,
                                                      combined_flux,
                                                      window_length=0.3,
                                                      method='hspline',
                                                      return_trend=True)
            flatten_lc_after, trend_after = flatten(t_cut,
                                                    flux_cut,
                                                    window_length=0.3,
                                                    method='hspline',
                                                    return_trend=True)

            # Plot before peak removal
            wotan_original_lc_fig = plt.figure()
            plt.scatter(lc_30min.time, flatten_lc_before, c='k', s=2)
            plt.xlabel('Time - 2457000 [BTJD days]')
            plt.ylabel("Relative flux")
            plt.title(
                '{} lc after standard wotan detrending - before peak removal'.
Ejemplo n.º 22
0
def tls_search(time, flux, epoch, period, rplanet, min_snr, transit_template):
    SNR = 1e12
    FOUND_SIGNAL = False

    #::: mask out the first detection at 6.2 days, with a duration of 2.082h, and T0=1712.54922
    # intransit = transit_mask(time, 6.26391, 2*2.082/24., 1712.54922)
    # time = time[~intransit]
    # flux = flux[~intransit]
    time, flux = cleaned_array(time, flux)
    run = 0
    flux = wotan.flatten(time, flux, window_length=0.25, return_trend=False, method='biweight',
                  break_tolerance=0.5)
    #::: search for the rest
    while (SNR >= min_snr) and (not FOUND_SIGNAL):
        model = transitleastsquares(time, flux)
        R_starx = rstar / u.R_sun
        results = model.power(u=ab,
                              R_star=radius,  # rstar/u.R_sun,
                              R_star_min=rstar_min,  # rstar_min/u.R_sun,
                              R_star_max=rstar_max,  # rstar_max/u.R_sun,
                              M_star=mass,  # mstar/u.M_sun,
                              M_star_min=mstar_min,  # mstar_min/u.M_sun,
                              M_star_max=mstar_max,  # mstar_max/u.M_sun,
                              period_min=0.5,
                              period_max=14,
                              n_transits_min=2,
                              show_progress_bar=False,
                              use_threads=20,
                              transit_template=transit_template
                              )

        # mass and radius for the TLS
        # rstar=radius
        ##mstar=mass
        # mstar_min = mass-massmin
        # mstar_max = mass+massmax
        # rstar_min = radius-radiusmin
        # rstar_max = radius+raduismax
        SNR = results.snr
        if results.snr >= min_snr:
            intransit = transit_mask(time, results.period, 2 * results.duration, results.T0)
            time = time[~intransit]
            flux = flux[~intransit]
            time, flux = cleaned_array(time, flux)

            #::: check if it found the right signal
            right_period = IsMultipleOf(results.period,
                                        period / 2.)  # check if it is a multiple of half the period to within 5%

            right_epoch = False
            for tt in results.transit_times:
                for i in range(-5, 5):
                    right_epoch = right_epoch or (np.abs(tt - epoch + i * period) < (
                                1. / 24.))  # check if any epochs matches to within 1 hour

            #            right_depth   = (np.abs(np.sqrt(1.-results.depth)*rstar - rplanet)/rplanet < 0.05) #check if the depth matches

            if right_period and right_epoch:
                FOUND_SIGNAL = True
                break
        run = run + 1
    return FOUND_SIGNAL, results.snr, run
Ejemplo n.º 23
0
def main():
    print("Starting tests for wotan...")

    numpy.testing.assert_almost_equal(t14(R_s=1, M_s=1, P=365),
                                      0.6490025258902046)

    numpy.testing.assert_almost_equal(
        t14(R_s=1, M_s=1, P=365, small_planet=True), 0.5403690143737738)
    print("Transit duration correct.")

    numpy.random.seed(seed=0)  # reproducibility

    print("Slide clipper...")
    points = 1000
    time = numpy.linspace(0, 30, points)
    flux = 1 + numpy.sin(time) / points
    noise = numpy.random.normal(0, 0.0001, points)
    flux += noise

    for i in range(points):
        if i % 75 == 0:
            flux[i:i + 5] -= 0.0004  # Add some transits
            flux[i + 50:i + 52] += 0.0002  # and flares

    clipped = slide_clip(time,
                         flux,
                         window_length=0.5,
                         low=3,
                         high=2,
                         method='mad',
                         center='median')
    numpy.testing.assert_almost_equal(numpy.nansum(clipped), 948.9926368754939)
    """
    import matplotlib.pyplot as plt
    plt.scatter(time, flux, s=3, color='black')
    plt.scatter(time, clipped, s=3, color='orange')
    plt.show()
    """

    # TESS test
    print('Loading TESS data from archive.stsci.edu...')
    path = 'https://archive.stsci.edu/hlsps/tess-data-alerts/'
    filename = "hlsp_tess-data-alerts_tess_phot_00062483237-s01_tess_v1_lc.fits"
    #path = 'P:/P/Dok/tess_alarm/'
    #filename = "hlsp_tess-data-alerts_tess_phot_00062483237-s01_tess_v1_lc.fits"
    #filename = 'P:/P/Dok/tess_alarm/hlsp_tess-data-alerts_tess_phot_00077031414-s02_tess_v1_lc.fits'
    #filename = 'tess2018206045859-s0001-0000000201248411-111-s_llc.fits'
    time, flux = load_file(path + filename)

    window_length = 0.5

    print("Detrending 1 (biweight)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length,
                                   edge_cutoff=1,
                                   break_tolerance=0.1,
                                   return_trend=True,
                                   cval=5.0)

    numpy.testing.assert_equal(len(trend_lc), 20076)
    numpy.testing.assert_almost_equal(numpy.nanmax(trend_lc),
                                      28754.985299070882)
    numpy.testing.assert_almost_equal(numpy.nanmin(trend_lc),
                                      28615.108124724477)
    numpy.testing.assert_almost_equal(trend_lc[500], 28671.686308143515)

    numpy.testing.assert_equal(len(flatten_lc), 20076)
    numpy.testing.assert_almost_equal(numpy.nanmax(flatten_lc),
                                      1.0034653549250616)
    numpy.testing.assert_almost_equal(numpy.nanmin(flatten_lc),
                                      0.996726610702177)
    numpy.testing.assert_almost_equal(flatten_lc[500], 1.000577429565131)

    print("Detrending 2 (andrewsinewave)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length,
                                   method='andrewsinewave',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18119.15471987987,
                                      decimal=2)

    print("Detrending 3 (welsch)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length,
                                   method='welsch',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18119.16764691235,
                                      decimal=2)

    print("Detrending 4 (hodges)...")
    flatten_lc, trend_lc = flatten(time[:1000],
                                   flux[:1000],
                                   window_length,
                                   method='hodges',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      994.0110525909206,
                                      decimal=2)

    print("Detrending 5 (median)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length,
                                   method='median',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18119.122065014355,
                                      decimal=2)

    print("Detrending 6 (mean)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length,
                                   method='mean',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18119.032473037714,
                                      decimal=2)

    print("Detrending 7 (trim_mean)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length,
                                   method='trim_mean',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18119.095164910334,
                                      decimal=2)

    print("Detrending 8 (supersmoother)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length,
                                   method='supersmoother',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18123.00632204841,
                                      decimal=2)

    print("Detrending 9 (hspline)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length,
                                   method='hspline',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18123.07625225313,
                                      decimal=2)

    print("Detrending 10 (cofiam)...")
    flatten_lc, trend_lc = flatten(time[:2000],
                                   flux[:2000],
                                   window_length,
                                   method='cofiam',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      1948.9999999987976,
                                      decimal=2)

    print("Detrending 11 (savgol)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length=301,
                                   method='savgol',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18123.003465539354,
                                      decimal=2)

    print("Detrending 12 (medfilt)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   window_length=301,
                                   method='medfilt',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18123.22609806557,
                                      decimal=2)

    print("Detrending 12 (gp squared_exp)...")
    flatten_lc, trend_lc1 = flatten(time[:2000],
                                    flux[:2000],
                                    method='gp',
                                    kernel='squared_exp',
                                    kernel_size=10,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      1948.99958552324,
                                      decimal=2)

    print("Detrending 13 (gp squared_exp robust)...")
    flatten_lc, trend_lc1 = flatten(time[:2000],
                                    flux[:2000],
                                    method='gp',
                                    kernel='squared_exp',
                                    kernel_size=10,
                                    robust=True,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      1948.8820772313468,
                                      decimal=2)

    print("Detrending 14 (gp matern)...")
    flatten_lc, trend_lc2 = flatten(time[:2000],
                                    flux[:2000],
                                    method='gp',
                                    kernel='matern',
                                    kernel_size=10,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      1949.0001583058202,
                                      decimal=2)

    print("Detrending 15 (gp periodic)...")
    flatten_lc, trend_lc2 = flatten(time[:2000],
                                    flux[:2000],
                                    method='gp',
                                    kernel='periodic',
                                    kernel_size=1,
                                    kernel_period=10,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      1948.9999708985608,
                                      decimal=2)

    time_synth = numpy.linspace(0, 30, 200)
    flux_synth = numpy.sin(time_synth) + numpy.random.normal(0, 0.1, 200)
    flux_synth = 1 + flux_synth / 100
    time_synth *= 1.5
    print("Detrending 16 (gp periodic_auto)...")
    flatten_lc, trend_lc2 = flatten(time_synth,
                                    flux_synth,
                                    method='gp',
                                    kernel='periodic_auto',
                                    kernel_size=1,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc), 200, decimal=1)

    print("Detrending 17 (rspline)...")
    flatten_lc, trend_lc2 = flatten(time,
                                    flux,
                                    method='rspline',
                                    window_length=1,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18121.812790732245,
                                      decimal=2)

    print("Detrending 18 (huber)...")
    flatten_lc, trend_lc = flatten(time[:1000],
                                   flux[:1000],
                                   method='huber',
                                   window_length=0.5,
                                   edge_cutoff=0,
                                   break_tolerance=0.4,
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      994.01102,
                                      decimal=2)

    print("Detrending 19 (winsorize)...")
    flatten_lc, trend_lc2 = flatten(time,
                                    flux,
                                    method='winsorize',
                                    window_length=0.5,
                                    edge_cutoff=0,
                                    break_tolerance=0.4,
                                    proportiontocut=0.1,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18119.064587196448,
                                      decimal=2)

    print("Detrending 20 (pspline)...")
    flatten_lc, trend_lc = flatten(time,
                                   flux,
                                   method='pspline',
                                   return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18121.832133916843,
                                      decimal=2)

    print("Detrending 21 (hampelfilt)...")
    flatten_lc, trend_lc5 = flatten(time,
                                    flux,
                                    method='hampelfilt',
                                    window_length=0.5,
                                    cval=3,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18119.158072498867,
                                      decimal=2)

    print("Detrending 22 (lowess)...")
    flatten_lc, trend_lc1 = flatten(time,
                                    flux,
                                    method='lowess',
                                    window_length=1,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18123.08085676265,
                                      decimal=2)

    print("Detrending 23 (huber_psi)...")
    flatten_lc, trend_lc1 = flatten(time,
                                    flux,
                                    method='huber_psi',
                                    window_length=0.5,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18119.122065014355,
                                      decimal=2)

    print("Detrending 24 (tau)...")
    flatten_lc, trend_lc2 = flatten(time,
                                    flux,
                                    method='tau',
                                    window_length=0.5,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      18119.02772621119,
                                      decimal=2)

    import numpy as np
    points = 1000
    time = np.linspace(0, 30, points)
    flux = 1 + np.sin(time) / points
    noise = np.random.normal(0, 0.0001, points)
    flux += noise

    for i in range(points):
        if i % 75 == 0:
            flux[i:i + 5] -= 0.0004  # Add some transits
            flux[i + 50:i + 52] += 0.0002  # and flares

    print("Detrending 25a (hampel 17A)...")
    flatten_lc, trend_lc1 = flatten(time,
                                    flux,
                                    method='hampel',
                                    cval=(1.7, 3.4, 8.5),
                                    window_length=0.5,
                                    return_trend=True)

    print("Detrending 25b (hampel 25A)...")
    flatten_lc, trend_lc2 = flatten(time,
                                    flux,
                                    method='hampel',
                                    cval=(2.5, 4.5, 9.5),
                                    window_length=0.5,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      997.9994362858843,
                                      decimal=2)

    print("Detrending 26 (ramsay)...")
    flatten_lc, trend_lc3 = flatten(time,
                                    flux,
                                    method='ramsay',
                                    cval=0.3,
                                    window_length=0.5,
                                    return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc),
                                      997.9974021484584,
                                      decimal=2)
    """
    import matplotlib.pyplot as plt
    plt.scatter(time, flux, s=1, color='black')
    plt.plot(time[:len(trend_lc1)], trend_lc1, color='blue', linewidth=2)
    plt.plot(time[:len(trend_lc1)], trend_lc2, color='red', linewidth=2, linestyle='dashed')
    plt.show()
    plt.close()
    #plt.scatter(time, flatten_lc, s=1, color='black')
    #plt.show()
    """

    print('All tests completed.')
Ejemplo n.º 24
0
def prepare_ttv_fit(datadir, ax=None):
    '''
    this must be run *after* reduce_phot_data()
    '''
    ax0 = ax
    
    alles = allesfitter.allesclass(datadir)
    window = alles.settings['fast_fit_width']
       
    if not os.path.exists( os.path.join(datadir,'ttv_preparation') ): os.makedirs(os.path.join(datadir,'ttv_preparation'))
    with open(os.path.join(datadir,'ttv_preparation','ttv_initial_guess_params.csv'),'w') as f:
        f.write('')
    
    def plot_all_transits_color_coded():
        for inst in alles.settings['inst_phot']:
            time = alles.data[inst]['time']
            for companion in alles.settings['companions_phot']:
                ind = []
                for i, t in enumerate(alles.data[companion+'_tmid_observed_transits']):
                    ind += list( np.where((time >= (t - window/2.)) & (time <= (t + window/2.)))[0] )
                ax.plot( alles.data[inst]['time'][ind], alles.data[inst]['flux'][ind], ls='none', marker='.', label=companion )
    
    
    for companion in alles.settings['companions_phot']:
        with open(os.path.join(datadir,'ttv_preparation','ttv_initial_guess_params.csv'),'a') as f:
            f.write('#TTV companion '+companion+',,,,,\n')
        
        #----------------------------------------------------------------------
        #::: get combined data from all instruments
        #----------------------------------------------------------------------
        all_times = []
        all_flux = []
        for inst in alles.settings['inst_phot']:
            all_times += list(alles.data[inst]['time'])
            all_flux += list(alles.data[inst]['flux'])
        ind_sort = np.argsort(all_times)
        all_times = np.array(all_times)[ind_sort]
        all_flux = np.array(all_flux)[ind_sort]
        
        #----------------------------------------------------------------------
        #::: get eclipse window
        #----------------------------------------------------------------------
        alles.initial_guess_params_median[companion+'_epoch']
        eclipse_width = eclipse_width_smart(alles.initial_guess_params_median[companion+'_period'], 
                                    alles.initial_guess_params_median[companion+'_rr'], 
                                    alles.initial_guess_params_median[companion+'_rsuma'], 
                                    alles.initial_guess_params_median[companion+'_cosi'], 
                                    alles.initial_guess_params_median[companion+'_f_s'], 
                                    alles.initial_guess_params_median[companion+'_f_c'], 
                                    )[0]
        
        #----------------------------------------------------------------------
        #::: compute tmid, ttv_guess and make per-transit-plots
        #----------------------------------------------------------------------
        tmids = []
        
        alles.data[companion+'_tmid_observed_transits'] = get_tmid_observed_transits(all_times,alles.initial_guess_params_median[companion+'_epoch'],alles.initial_guess_params_median[companion+'_period'],alles.settings['fast_fit_width'])
        N = len(alles.data[companion+'_tmid_observed_transits'])
        fig, axes = plt.subplots(N, 1, figsize=(6,4*N), sharey=True, tight_layout=True)
        
        for i, t in enumerate(alles.data[companion+'_tmid_observed_transits']):
            ind_tr1 = np.where((all_times >= (t - window/2.)) & (all_times <= (t + window/2.)))[0]
            tr_times = all_times[ind_tr1]
            tr_flux = all_flux[ind_tr1]
            t_exp = np.median(np.diff(tr_times))
            N_points_in_eclipse = int(eclipse_width/t_exp)
            try:
                trend = flatten(tr_times, tr_flux, window_length=eclipse_width/2., method='biweight', return_trend=True)[1]
                tmid = np.median( tr_times[ np.argsort(trend)[0:int(N_points_in_eclipse/2.)] ] )
            except:
                warnings.warn('Install wotan for improved performance of prepare_ttv_fit().')
                trend = None
                tmid = np.median( tr_times[ np.argsort(tr_times)[0:int(N_points_in_eclipse/2.)] ] )
            ttv_guess = tmid - t
            tmids.append(tmid)
            
            ax = axes[i]
            ax.plot(tr_times, tr_flux, 'b.', rasterized=True)
            if trend is not None: ax.plot(tr_times, trend, 'r-')
            ax.axvline(t,c='grey',ls='--',label='linear prediction')
            ax.axvline(tmid,c='r',ls='--',label='flux minimum')
            ax.set(xlabel='Time', ylabel='Flux', xlim=[t-window/2., t+window/2.])
            ax.text(0.95,0.95,'Transit '+str(i+1), va='top', ha='right', transform=ax.transAxes)
            with open(os.path.join(datadir,'ttv_preparation','ttv_initial_guess_params.csv'),'a') as f:
               f.write(companion+'_ttv_transit_'+str(i+1)+','+np.format_float_positional(ttv_guess,4)+',1,uniform '+np.format_float_positional(ttv_guess-0.01,4)+' '+np.format_float_positional(ttv_guess+0.01,4)+',TTV$_\mathrm{'+companion+';'+str(i+1)+'}$,d\n')
        axes[0].legend()
        fig.savefig(os.path.join(datadir,'ttv_preparation','ttv_preparation_'+companion+'_per_transit.pdf'), bbox_inches='tight')
        plt.close(fig)
         
        tmids = np.array(tmids)
        
        
        #----------------------------------------------------------------------
        #::: ttv guess 0-C plot
        #----------------------------------------------------------------------
        nr = np.array([ int(np.round( (t-tmids[0]) / alles.initial_guess_params_median[companion+'_period'] )) for t in tmids ]) #get corresponding transit number
        nr -= int(nr[-1]/2.) #shift into the middle of the data set
        period_mean, epoch_mean = np.polyfit(nr, tmids, 1)             
        
        fig, axes = plt.subplots(2,1,figsize=(6,8),tight_layout=True,sharex=True)
        axes[0].plot(nr, tmids, 'bo', label='Companion '+companion)
        axes[0].plot(nr, epoch_mean + nr * period_mean, 'b-')
        axes[0].set(xlabel='Nr.', ylabel='Transit mid-time')
        axes[0].legend()
        axes[1].plot(nr, tmids-(epoch_mean + nr * period_mean), 'bo')
        axes[1].axhline(0,c='grey',ls='--')
        fig.savefig(os.path.join(datadir,'ttv_preparation','ttv_preparation_'+companion+'_oc.pdf'), bbox_inches='tight')
        
        period_dev = np.abs( (period_mean-alles.initial_guess_params_median[companion+'_period'])/alles.initial_guess_params_median[companion+'_period'] )
        epoch_dev = np.abs( (epoch_mean-alles.initial_guess_params_median[companion+'_epoch'])/alles.initial_guess_params_median[companion+'_epoch'] )
        
        print('\nCompanion', companion)
        print('Initial guess for mean period and epoch:')
        print(np.format_float_positional(alles.initial_guess_params_median[companion+'_period']), 
              np.format_float_positional(alles.initial_guess_params_median[companion+'_epoch']))
        print('New estimate for mean period and epoch:')
        print(np.format_float_positional(period_mean,4), 
              np.format_float_positional(epoch_mean,4))
        # print('Deviation from another:')
        # print(np.format_float_positional(period_dev,4), 
        #       np.format_float_positional(epoch_dev,4))
        if (period_dev > 0.01) or (epoch_dev > 0.01):
            print('\n! Consider updating your initial guess to these new estimated mean values.')
            print('\n! If you do, then you must rerun this code.')
        else:
            print('\n! Looks great! You are ready to fit.')

        
        #----------------------------------------------------------------------
        #::: full lightcurve plot
        #----------------------------------------------------------------------
        flux_min = np.nanmin(all_flux)
        flux_max = np.nanmax(all_flux)
        if ax0 is None:
            days = np.max(all_times) - np.min(all_times)
            figsizex = np.max( [5, 5*(days/10.)] )
            fig, ax = plt.subplots(figsize=(figsizex, 4)) #figsize * 5 for every 20 days
        for inst in alles.settings['inst_phot']:
            ax.plot(alles.fulldata[inst]['time'], alles.fulldata[inst]['flux'],ls='none',marker='.',color='silver')
            # ax.plot(alles.data[inst]['time'], alles.data[inst]['flux'],ls='none',marker='.',label=inst) #color code by instrument
        plot_all_transits_color_coded() #color code by companion
                
        ax.plot( alles.data[companion+'_tmid_observed_transits'], np.ones_like(alles.data[companion+'_tmid_observed_transits'])*0.997*flux_min, 'k^', zorder=12 )
        for i, tmid in enumerate(alles.data[companion+'_tmid_observed_transits']):
            ax.text( tmid, 0.992*flux_min, str(i+1), ha='center', zorder=12 )  
            ax.axvline( tmid, color='grey', zorder=11 )
        ax.set(ylim=[0.99*flux_min, 1.002*flux_max], xlabel='Time (BJD)', ylabel='Realtive Flux', title='Companion '+companion) 
        ax.legend(loc='best')
    
        fname = os.path.join(datadir,'ttv_preparation','ttv_preparation_'+companion+'.jpg')
        fig = plt.gcf()
        fig.savefig(fname, bbox_inches='tight' )  
        plt.close(fig)
                
Ejemplo n.º 25
0
    def calculate(self):

        
        if self.ui.radio_remove_median.isChecked():

            flatten_lc1 = self.flux/np.median(self.flux)
            trend_lc1 = np.ones(len(self.flux))*np.median(self.flux)

        elif self.ui.radio_remove_mean.isChecked():

            flatten_lc1 = self.flux/np.mean(self.flux)
            trend_lc1 = np.ones(len(self.flux))*np.mean(self.flux)

        elif self.ui.radio_timeW.isChecked():
            flatten_lc1, trend_lc1 = flatten(
                self.t,                 # Array of time values
                self.flux ,                 # Array of flux values
                method=str(self.ui.comboBox_sliders.currentText()),
                window_length=self.ui.sliders_wl.value(),    # The length of the filter window in units of ``time``
#                break_tolerance=self.ui.spline_bt.value(),  # Split into segments at breaks longer than that
                return_trend=True,    # Return trend and flattened light curve
                )

        elif self.ui.radio_Splines.isChecked():
            flatten_lc1, trend_lc1 = flatten(
                self.t,                 # Array of time values
                self.flux ,                 # Array of flux values
                method=str(self.ui.comboBox_splines.currentText()),
                window_length=self.ui.spline_wl.value(),    # The length of the filter window in units of ``time``
                break_tolerance=self.ui.spline_bt.value(),  # Split into segments at breaks longer than that
                return_trend=True,    # Return trend and flattened light curve
                )

        elif self.ui.radio_Polynomials.isChecked():

            flatten_lc1, trend_lc1 = flatten(
                self.t,                 # Array of time values
                self.flux ,                 # Array of flux values
                method=str(self.ui.comboBox_poly.currentText()),
                window_length=self.ui.poly_wl.value(),    # The length of the filter window in units of ``time``
                break_tolerance=self.ui.poly_bt.value(),  # Split into segments at breaks longer than that
                return_trend=True,    # Return trend and flattened light curve
                )

        elif self.ui.radio_Regressions.isChecked():

            flatten_lc1, trend_lc1 = flatten(
                self.t,                 # Array of time values
                self.flux ,                 # Array of flux values
                method=str(self.ui.comboBox_regs.currentText()),
                window_length=self.ui.regres_wl.value(),    # The length of the filter window in units of ``time``
                break_tolerance=self.ui.regres_bt.value(),  # Split into segments at breaks longer than that
                return_trend=True,    # Return trend and flattened light curve
                )
            
        elif self.ui.radio_GPs.isChecked():

            flatten_lc1, trend_lc1 = flatten(
                self.t,                 # Array of time values
                self.flux ,                 # Array of flux values
                method='gp',
                kernel = str(self.ui.comboBox_GP.currentText()),
                kernel_size=self.ui.kernel_size.value(),
                break_tolerance=self.ui.regres_bt.value(),  # Split into segments at breaks longer than that
                kernel_period = self.ui.GP_period.value(),
                robust = self.ui.checkBox_GP_robust.isChecked(),
                return_trend=True    # Return trend and flattened light curve
                )

        else:
            flatten_lc1 = self.flux 
            trend_lc1 = np.ones(len(self.flux))*np.median(self.flux)


        self.flux_o_c = flatten_lc1
        self.trend = trend_lc1
        self.flux_err_o_c = self.flux_err/trend_lc1
Ejemplo n.º 26
0
def main():
    print("Starting tests for wotan...")

    numpy.testing.assert_almost_equal(t14(R_s=1, M_s=1, P=365), 0.6490025258902046)

    numpy.testing.assert_almost_equal(
        t14(R_s=1, M_s=1, P=365, small_planet=True), 0.5403690143737738
    )
    print("Transit duration correct.")

    numpy.random.seed(seed=0)  # reproducibility

    print("Slide clipper...")
    points = 1000
    time = numpy.linspace(0, 30, points)
    flux = 1 + numpy.sin(time) / points
    noise = numpy.random.normal(0, 0.0001, points)
    flux += noise

    for i in range(points):
        if i % 75 == 0:
            flux[i : i + 5] -= 0.0004  # Add some transits
            flux[i + 50 : i + 52] += 0.0002  # and flares

    clipped = slide_clip(
        time, flux, window_length=0.5, low=3, high=2, method="mad", center="median"
    )
    numpy.testing.assert_almost_equal(numpy.nansum(clipped), 948.9926368754939)

    """
    import matplotlib.pyplot as plt
    plt.scatter(time, flux, s=3, color='black')
    plt.scatter(time, clipped, s=3, color='orange')
    plt.show()
    """

    # TESS test
    print("Loading TESS data from archive.stsci.edu...")
    path = "https://archive.stsci.edu/hlsps/tess-data-alerts/"
    # path = 'P:/P/Dok/tess_alarm/'
    filename = "hlsp_tess-data-alerts_tess_phot_00062483237-s01_tess_v1_lc.fits"
    time, flux = load_file(path + filename)

    window_length = 0.5
    print("Detrending 1 (biweight)...")
    flatten_lc, trend_lc = flatten(
        time,
        flux,
        window_length,
        edge_cutoff=1,
        break_tolerance=0.1,
        return_trend=True,
        cval=5.0,
    )

    numpy.testing.assert_equal(len(trend_lc), 20076)
    numpy.testing.assert_almost_equal(
        numpy.nanmax(trend_lc), 28755.03811866676, decimal=2
    )
    numpy.testing.assert_almost_equal(
        numpy.nanmin(trend_lc), 28615.110229935075, decimal=2
    )
    numpy.testing.assert_almost_equal(trend_lc[500], 28671.650565730513, decimal=2)

    numpy.testing.assert_equal(len(flatten_lc), 20076)
    numpy.testing.assert_almost_equal(
        numpy.nanmax(flatten_lc), 1.0034653549250616, decimal=2
    )
    numpy.testing.assert_almost_equal(
        numpy.nanmin(flatten_lc), 0.996726610702177, decimal=2
    )
    numpy.testing.assert_almost_equal(flatten_lc[500], 1.000577429565131, decimal=2)

    print("Detrending 2 (andrewsinewave)...")
    flatten_lc, trend_lc = flatten(
        time, flux, window_length, method="andrewsinewave", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.15456308313, decimal=2
    )

    print("Detrending 3 (welsch)...")
    flatten_lc, trend_lc = flatten(
        time, flux, window_length, method="welsch", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.16770590837, decimal=2
    )

    print("Detrending 4 (hodges)...")
    flatten_lc, trend_lc = flatten(
        time[:1000], flux[:1000], window_length, method="hodges", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 996.0113241694287, decimal=2
    )

    print("Detrending 5 (median)...")
    flatten_lc, trend_lc = flatten(
        time, flux, window_length, method="median", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.12166552401, decimal=2
    )

    print("Detrending 6 (mean)...")
    flatten_lc, trend_lc = flatten(
        time, flux, window_length, method="mean", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.032058753546, decimal=2
    )

    print("Detrending 7 (trim_mean)...")
    flatten_lc, trend_lc = flatten(
        time, flux, window_length, method="trim_mean", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.094751124332, decimal=2
    )

    print("Detrending 8 (supersmoother)...")
    flatten_lc, trend_lc = flatten(
        time, flux, window_length, method="supersmoother", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.00632204841, decimal=2
    )

    print("Detrending 9 (hspline)...")
    flatten_lc, trend_lc = flatten(
        time, flux, window_length, method="hspline", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.082601463717, decimal=1
    )

    print("Detrending 10 (cofiam)...")
    flatten_lc, trend_lc = flatten(
        time[:2000], flux[:2000], window_length, method="cofiam", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 1948.9999999987976, decimal=1
    )

    print("Detrending 11 (savgol)...")
    flatten_lc, trend_lc = flatten(
        time, flux, window_length=301, method="savgol", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.003465539354, decimal=1
    )

    print("Detrending 12 (medfilt)...")
    flatten_lc, trend_lc = flatten(
        time, flux, window_length=301, method="medfilt", return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.22609806557, decimal=1
    )

    print("Detrending 12 (gp squared_exp)...")
    flatten_lc, trend_lc1 = flatten(
        time[:2000],
        flux[:2000],
        method="gp",
        kernel="squared_exp",
        kernel_size=10,
        return_trend=True,
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 1948.9672036416687, decimal=2
    )

    print("Detrending 13 (gp squared_exp robust)...")
    flatten_lc, trend_lc1 = flatten(
        time[:2000],
        flux[:2000],
        method="gp",
        kernel="squared_exp",
        kernel_size=10,
        robust=True,
        return_trend=True,
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 1948.8820772313468, decimal=2
    )

    print("Detrending 14 (gp matern)...")
    flatten_lc, trend_lc2 = flatten(
        time[:2000],
        flux[:2000],
        method="gp",
        kernel="matern",
        kernel_size=10,
        return_trend=True,
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 1948.9672464898367, decimal=2
    )

    print("Detrending 15 (gp periodic)...")
    flatten_lc, trend_lc2 = flatten(
        time[:2000],
        flux[:2000],
        method="gp",
        kernel="periodic",
        kernel_size=1,
        kernel_period=10,
        return_trend=True,
    )

    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 1948.9999708985608, decimal=2
    )

    time_synth = numpy.linspace(0, 30, 200)
    flux_synth = numpy.sin(time_synth) + numpy.random.normal(0, 0.1, 200)
    flux_synth = 1 + flux_synth / 100
    time_synth *= 1.5
    print("Detrending 16 (gp periodic_auto)...")
    flatten_lc, trend_lc2 = flatten(
        time_synth,
        flux_synth,
        method="gp",
        kernel="periodic_auto",
        kernel_size=1,
        return_trend=True,
    )
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc), 200, decimal=1)

    print("Detrending 17 (rspline)...")
    flatten_lc, trend_lc2 = flatten(
        time, flux, method="rspline", window_length=1, return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18121.812790732245, decimal=2
    )
    """
    print("Detrending 18 (huber)...")
    flatten_lc, trend_lc = flatten(
        time[:1000],
        flux[:1000],
        method='huber',
        window_length=0.5,
        edge_cutoff=0,
        break_tolerance=0.4,
        return_trend=True)
    numpy.testing.assert_almost_equal(numpy.nansum(flatten_lc), 996.0112964009066, decimal=2)
    """
    print("Detrending 19 (winsorize)...")
    flatten_lc, trend_lc2 = flatten(
        time,
        flux,
        method="winsorize",
        window_length=0.5,
        edge_cutoff=0,
        break_tolerance=0.4,
        proportiontocut=0.1,
        return_trend=True,
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.064149766662, decimal=2
    )

    print("Detrending 20 (pspline)...")
    flatten_lc, trend_lc = flatten(time, flux, method="pspline", return_trend=True)
    # import matplotlib.pyplot as plt
    # plt.scatter(time, flux, s=3, color='black')
    # plt.plot(time, trend_lc)
    # plt.show()

    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18122.740535799767, decimal=2
    )

    print("Detrending 21 (hampelfilt)...")
    flatten_lc, trend_lc5 = flatten(
        time, flux, method="hampelfilt", window_length=0.5, cval=3, return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.157973016467, decimal=2
    )

    print("Detrending 22 (lowess)...")
    flatten_lc, trend_lc1 = flatten(
        time, flux, method="lowess", window_length=1, return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.039744125545, decimal=2
    )

    print("Detrending 23 (huber_psi)...")
    flatten_lc, trend_lc1 = flatten(
        time, flux, method="huber_psi", window_length=0.5, return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.110893063527, decimal=2
    )

    print("Detrending 24 (tau)...")
    flatten_lc, trend_lc2 = flatten(
        time, flux, method="tau", window_length=0.5, return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18123.026005725977, decimal=2
    )

    print("Detrending 25 (cosine)...")
    flatten_lc, trend_lc2 = flatten(
        time, flux, method="cosine", window_length=0.5, return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18122.999999974905, decimal=2
    )

    print("Detrending 25 (cosine robust)...")
    flatten_lc, trend_lc2 = flatten(
        time, flux, method="cosine", robust=True, window_length=0.5, return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 18122.227938535038, decimal=2
    )

    import numpy as np

    points = 1000
    time = numpy.linspace(0, 30, points)
    flux = 1 + numpy.sin(time) / points
    noise = numpy.random.normal(0, 0.0001, points)
    flux += noise

    for i in range(points):
        if i % 75 == 0:
            flux[i : i + 5] -= 0.0004  # Add some transits
            flux[i + 50 : i + 52] += 0.0002  # and flares

    print("Detrending 26 (hampel 17A)...")
    flatten_lc, trend_lc1 = flatten(
        time,
        flux,
        method="hampel",
        cval=(1.7, 3.4, 8.5),
        window_length=0.5,
        return_trend=True,
    )

    print("Detrending 27 (hampel 25A)...")
    flatten_lc, trend_lc2 = flatten(
        time,
        flux,
        method="hampel",
        cval=(2.5, 4.5, 9.5),
        window_length=0.5,
        return_trend=True,
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 999.9992212031945, decimal=2
    )

    print("Detrending 28 (ramsay)...")
    flatten_lc, trend_lc3 = flatten(
        time, flux, method="ramsay", cval=0.3, window_length=0.5, return_trend=True
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 999.9970566765148, decimal=2
    )

    print("Detrending 29 (ridge)...")
    flatten_lc, trend_lc1 = flatten(
        time, flux, window_length=0.5, method="ridge", return_trend=True, cval=1
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 999.9999958887022, decimal=1
    )

    print("Detrending 30 (lasso)...")
    flatten_lc, trend_lc2 = flatten(
        time, flux, window_length=0.5, method="lasso", return_trend=True, cval=1
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 999.9999894829843, decimal=1
    )

    print("Detrending 31 (elasticnet)...")
    flatten_lc, trend_lc3 = flatten(
        time, flux, window_length=0.5, method="elasticnet", return_trend=True, cval=1
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 999.9999945063338, decimal=1
    )

    # Test of transit mask
    print("Testing transit_mask")
    filename = "hlsp_tess-data-alerts_tess_phot_00207081058-s01_tess_v1_lc.fits"
    time, flux = load_file(path + filename)

    from wotan import transit_mask

    mask = transit_mask(time=time, period=14.77338, duration=0.21060, T0=1336.141095)
    numpy.testing.assert_almost_equal(numpy.sum(mask), 302, decimal=1)

    print("Detrending 32 (transit_mask cosine)")
    flatten_lc1, trend_lc1 = flatten(
        time,
        flux,
        method="cosine",
        window_length=0.4,
        return_trend=True,
        robust=True,
        mask=mask,
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc1), 18119.281265446625, decimal=1
    )

    print("Detrending 33 (transit_mask lowess)")
    flatten_lc2, trend_lc2 = flatten(
        time,
        flux,
        method="lowess",
        window_length=0.8,
        return_trend=True,
        robust=True,
        mask=mask,
    )
    # print(numpy.nansum(flatten_lc2))
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc2), 18119.30865711536, decimal=1
    )

    print("Detrending 34 (transit_mask GP)")
    mask = transit_mask(time=time[:2000], period=100, duration=0.3, T0=1327.4)
    flatten_lc2, trend_lc2 = flatten(
        time[:2000],
        flux[:2000],
        method="gp",
        kernel="matern",
        kernel_size=0.8,
        return_trend=True,
        robust=True,
        mask=mask,
    )
    # print(numpy.nansum(flatten_lc2))
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc2), 1948.9000170463796, decimal=1
    )

    print("Detrending 35 (pspline full features)")
    flatten_lc, trend_lc, nsplines = flatten(
        time,
        flux,
        method="pspline",
        max_splines=100,
        edge_cutoff=0.5,
        return_trend=True,
        return_nsplines=True,
        verbose=True,
    )

    # print('lightcurve was split into', len(nsplines), 'segments')
    # print('chosen number of splines', nsplines)
    """
    import matplotlib.pyplot as plt
    plt.scatter(time, flux, s=3, color='black')
    plt.plot(time, trend_lc)
    plt.show()

    plt.scatter(time, flatten_lc, s=3, color='black')
    plt.show()
    """
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 16678.312693036027, decimal=1
    )

    print("Detrending 36 (pspline variable PSPLINES_STDEV_CUT)")
    flatten_lc, trend_lc, nsplines = flatten(
        time,
        flux,
        method="pspline",
        max_splines=100,
        edge_cutoff=0.5,
        stdev_cut=3,
        return_trend=True,
        return_nsplines=True,
        verbose=True,
    )
    numpy.testing.assert_almost_equal(
        numpy.nansum(flatten_lc), 16678.292210380347, decimal=2
    )

    """
    import matplotlib.pyplot as plt
    plt.scatter(time, flux, s=1, color='black')
    plt.plot(time, trend_lc, color='red', linewidth=2, linestyle='dashed')
    plt.show()
    plt.close()
    """

    print("All tests completed.")

cumulative_residuals = np.full(len(lc_time), np.nan)
residual_calculation = np.full((len(model_samples), len(lc_time)), np.nan)
depth_calculation = np.full((len(model_samples), len(lc_time)), np.nan)
for model_index, model_sample in enumerate(model_samples):
    model_duration_days = duration_grid[model_index] * cadence / 60 / 24
    first_valid_time = lc_time[lc_time > lc_time[0] +
                               model_duration_days * 3][0]
    time_without_tail = lc_time[lc_time < lc_time[len(lc_time) - 1] -
                                model_duration_days * 3]
    last_valid_time = time_without_tail[len(time_without_tail) - 1]
    first_valid_time = lc_time[0]
    last_valid_time = lc_time[len(lc_time) - 1 - len(model_sample)]
    dt_flux = wotan.flatten(lc_time,
                            flux,
                            model_duration_days * 4,
                            method="biweight")
    dt_flux = flux
    for flux_index, flux_value in enumerate(
            lc_time[(lc_time >= first_valid_time)
                    & (lc_time <= last_valid_time)]):
        residual, depth = calculate_residuals(lc_time, dt_flux, model_sample,
                                              flux_index)
        residual_calculation[model_index][flux_index] = residual
        depth_calculation[model_index][flux_index] = depth
    local_residual_minima = argrelextrema(residual_calculation[model_index],
                                          np.less)[0]
    minima_mask = np.full(len(residual_calculation[model_index]), False)
    minima_mask[local_residual_minima] = True
    max_allowed_residual = np.nanmax(residual_calculation[model_index])
    residual_calculation[model_index][np.where(
Ejemplo n.º 28
0
def flatten(lc,
            t0=None,
            period=None,
            duration=1. / 24.,
            window_length=3. / 24.,
            **kwargs):
    """
    Flatten a light curve using the `wotan` package.

    Parameters
    ----------
    lc : `~lightkurve.LightCurve`
        A light curve object with the data.

    t0 : float or iterable, optional
        Mid-transit time of transit signal(s) to mask.

    period : float or iterable, optional
        Period of transit signal(s) to mask.

    duration : float, optional
        Duration of transit signal to mask. Defaults to 1 hr.

    window_length : float, optional
        Length of the filter window for `wotan.flatten()`. Defaults to 3 hr.

    kwargs : dict, optional
        Any extra keyword arguments to pass to `wotan.flatten()`.

    Returns
    -------
    lc : `~lightkurve.LightCurve`
        A light curve object with the flattened light curve.

    trend : ndarray
        The removed flux trend. Only returned if ``return_trend`` is `True`.
    """
    # Mask transits if any ephemerides are given
    mask = np.zeros_like(lc.time, dtype=bool)
    if t0 is not None:
        t0s = np.array(t0).flatten()
        periods = np.array(period).flatten()
        for t0, period in zip(t0s, periods):
            mask += wotan.transit_mask(time=lc.time,
                                       T0=t0,
                                       period=period,
                                       duration=duration)

    # Flatten the light curve
    flux_flat = wotan.flatten(lc.time,
                              lc.flux,
                              window_length=window_length,
                              mask=mask,
                              **kwargs)

    # Return trend if return_trend=True
    return_trend = False
    if isinstance(flux_flat, tuple):
        return_trend = True
        flux_flat, trend = flux_flat

    lcflat = lc.copy()
    lcflat.flux = flux_flat

    if return_trend:
        return (lcflat, trend)
    else:
        return lcflat
Ejemplo n.º 29
0
def detrend_lightcurve_wotan(data, window_length=0.25, iscdips=True):

    #NOTE: junky. doesnt work.
    # try two simple harmonic oscillators with periods separated by a factor of
    # two...

    if iscdips:
        sector_data = data[0]
        time = sector_data['TMID_BJD']
        flux = vp._given_mag_get_flux(sector_data['IRM1'])
    else:
        d = data[0]
        time = d['TIME']
        flux = d['PDCSAP_FLUX'] / np.nanmedian(d['PDCSAP_FLUX'])

    from wotan import flatten

    _, trend_lc2 = flatten(
        time,  # Array of time values
        flux,  # Array of flux values
        method='biweight',
        robust=True,  # Iteratively clip 2-sigma outliers until convergence
        window_length=
        window_length,  # The length of the filter window in units of ``time``
        break_tolerance=0.5,  # Split into segments at breaks longer than that
        return_trend=True,  # Return trend and flattened light curve
    )
    if window_length == 99:
        trend_lc2 = np.ones_like(flux) * np.nanmedian(flux)

    # flatten_lc2, trend_lc2 = flatten(
    #         time,                  # Array of time values
    #         flux,                  # Array of flux values
    #         method='gp',
    #         kernel='periodic',     # GP kernel choice
    #         kernel_period=0.498818,  # GP kernel period
    #         kernel_size=50,        # GP kernel length
    #         break_tolerance=0.5,   # Split into segments at breaks longer than
    #         return_trend=True,     # Return trend and flattened light curve
    # )

    # plot!
    plt.close('all')
    if iscdips:
        f, axs = plt.subplots(nrows=2, ncols=1, figsize=(16, 7))
    else:
        f, axs = plt.subplots(nrows=2, ncols=1, figsize=(32, 7))

    axs[0].scatter(time, flux, c='k', s=5, zorder=2)
    axs[0].plot(time, trend_lc2, c='orange', lw=1, zorder=3)

    dtr_flux = flux - trend_lc2
    sel = ~np.isnan(dtr_flux)
    axs[1].scatter(time[sel], dtr_flux[sel], c='k', s=5)

    axs[1].set_xlabel('time [bjdtdb]')
    axs[0].set_ylabel('IRM1 flux')
    axs[1].set_ylabel('residual')

    axs[0].set_title('biweight detrend, {}d'.format(window_length))

    if not iscdips:
        axs[1].set_ylim([-0.1, 0.05])
        if window_length == 99:
            axs[1].set_ylim([-0.1, 0.1])

    isspoc = '' if iscdips else '_spoc2min'
    savpath = '../../results/quicklooklc/PTFO_8-8695/detrend_lc{}_{:.2f}d.png'.format(
        isspoc, window_length)
    f.savefig(savpath, dpi=300, bbox_inches='tight')
    print('made {}'.format(savpath))

    if not iscdips:

        from transitleastsquares import transitleastsquares
        model = transitleastsquares(
            time[sel], 1 + dtr_flux[sel] + np.nanmedian(dtr_flux[sel]))
        results = model.power(period_min=0.3,
                              period_max=0.6,
                              M_star_min=0.1,
                              M_star_max=5,
                              R_star=0.5,
                              M_star=0.5)

        print(42 * '-')
        print('t0: {}'.format(results.T0) +
              '\nperiod: {}'.format(results.period) +
              '\nperiod_unc: {}'.format(results.period_uncertainty))
        print(42 * '-')

        plt.close('all')
        fig = plt.figure()
        ax = plt.gca()
        ax.axvline(results.period, alpha=0.4, lw=3)
        plt.xlim(np.min(results.periods), np.max(results.periods))
        for n in range(2, 10):
            ax.axvline(n * results.period, alpha=0.4, lw=1, linestyle="dashed")
            ax.axvline(results.period / n, alpha=0.4, lw=1, linestyle="dashed")
        plt.ylabel(r'SDE')
        plt.xlabel('Period (days)')
        plt.plot(results.periods, results.power, color='black', lw=0.5)
        plt.xlim(0, max(results.periods))

        savpath = '../../results/quicklooklc/PTFO_8-8695/detrend_lc{}_{:.2f}d_periodogram.png'.format(
            isspoc, window_length)
        fig.savefig(savpath, dpi=300, bbox_inches='tight')
        print('made {}'.format(savpath))

        plt.close('all')
        fig = plt.figure()
        # plt.plot(results.model_folded_phase, results.model_folded_model,
        #          color='orange', zorder=3)
        plt.scatter(results.folded_phase,
                    results.folded_y,
                    color='gray',
                    s=2,
                    alpha=0.8,
                    zorder=4,
                    linewidths=0)

        pd = phase_bin_magseries(results.folded_phase,
                                 results.folded_y,
                                 binsize=0.01)

        plt.scatter(pd['binnedphases'],
                    pd['binnedmags'],
                    color='black',
                    s=8,
                    alpha=1,
                    zorder=5,
                    linewidths=0)

        #plt.xlim(0.35, 0.65)
        rstr = '(on residual)' if window_length <= 0.2 else '(on raw)'
        plt.title('{} period {:.8f}d'.format(rstr, results.period))
        plt.xlabel('Phase')
        plt.ylabel('Relative flux')
        plt.xticks([0, 0.25, 0.5, 0.75, 1])
        plt.grid(which='major',
                 axis='both',
                 linestyle='--',
                 zorder=-3,
                 alpha=0.5,
                 color='gray')

        pct_80 = np.percentile(results.model_folded_model, 80)
        pct_20 = np.percentile(results.model_folded_model, 20)
        center = np.nanmedian(results.model_folded_model)
        delta_y = (10 / 6) * np.abs(pct_80 - pct_20)
        plt.ylim((center - 0.7 * delta_y, center + 0.7 * delta_y))

        savpath = '../../results/quicklooklc/PTFO_8-8695/detrend_lc{}_{:.2f}d_phasefold.png'.format(
            isspoc, window_length)
        fig.savefig(savpath, dpi=300, bbox_inches='tight')
        print('made {}'.format(savpath))
Ejemplo n.º 30
0
#::: 2) prepare data
flux = sigma_clip(time, flux, high=3, low=20)
flux = slide_clip(time, flux, high=3, low=20)
flux = mask_regions(time,
                    flux,
                    regions=[(2458865.5, 2458866), (2458990, 2458990.5)])
tessplot(time, flux)

#::: 3) estimate variability period
period = estimate_period(time, flux, flux_err)[0]

#::: 4) detrend data
flux = slide_clip(time, flux, high=3, low=20)
flux_flat, trend = flatten(time,
                           flux,
                           method='biweight',
                           window_length=1,
                           return_trend=True)
tessplot(time, flux, trend=trend)
tessplot(time, flux_flat)
period = estimate_period(time, flux_flat, flux_err)[0]

#::: 5) search transits
kwargs = get_tls_kwargs_by_tic(tic_id)  #390651552 #459837008
results_all, fig_all = tls_search(time,
                                  flux_flat,
                                  flux_err,
                                  plot=True,
                                  period_min=1,
                                  period_max=20,
                                  **kwargs)