Beispiel #1
0
def get_period(t,f_t,outputpath='',starname=''):

  # here we use a BLS algorithm to create a periodogram and find the best periods. The BLS is implemented in Python by Ruth Angus and Dan Foreman-Mackey

  outputfolder = os.path.join(outputpath,str(starname))
  fmin = 2.0/((t[len(t)-1]-t[0])) # minimum frequency. we can't find anything longer than 90 days obviously
  nf = 1e5 # amount of frequencies to try
  df = 1e-4#0.00001 # frequency step

  qmi = 0.0005 # min relative length of transit (in phase unit)
  qma = 0.1 # max relative length of transit (in phase unit)
  nb = 200 # number of bins in folded LC

  u = np.linspace(fmin,fmin + nf*df,nf)
  v = np.array(0)
  t = np.array(t)
  f_t = np.array(f_t)

  t_orig = np.copy(t)
  f_t_orig = f_t

  results = bls.eebls(t,f_t,t,f_t,nf,fmin,df,nb,qmi,qma)
  freqlist = u
  powers = results[0]
  period = results[1]

  folded,f_t_folded = fold_data(t,f_t,period)

  np.savetxt(os.path.join(outputfolder, 'PhaseFolded.txt'),np.transpose([folded,f_t_folded]),header='Time, Flux')

  t_foldbin,f_t_foldbin,stdv_foldbin = rebin_dataset(folded,f_t_folded,15)
  f_t_smooth = savitzky_golay(f_t_folded,29,1)
  pl.figure('my data folded bls')
  pl.plot(folded,f_t_folded+1.,'.',color='black',label='K2 photometry')
  pl.xlabel('Time [d]')
  pl.ylabel('Relative Flux')
  pl.savefig(os.path.join(outputfolder, 'PhaseFolded.png'))
  pl.close('all')


  # unravel again
  n_start = int(np.round(t[0] / period))
  n_end = np.round(t[-1] / period) + 1
  i = n_start

  t_unravel = []
  f_t_unravel = []
  while i < n_end:
    t_unravel.append(np.array(folded) + i*period + t_orig[0])
    f_t_unravel.append(np.array(f_t_smooth))

    pl.plot(t_unravel[i],f_t_unravel[i],color='black',lw='1.5')
    i = i + 1

  if abs(period-0.24)<0.01:
    freqlist,powers = maskout_freqs(freqlist,powers,freq=0.245) # spacecraft freqs
    Location = np.where(powers==max(powers))
    period = freqlist[Location[0]][0]
  print "The best period is: ", period
  return folded,f_t_folded,period,freqlist,powers
 def BLS(self,time, lc, df = 0.0001, nf = 500,  nb = 200, qmi = 0.01,\
     qma = 0.8, fmin = (1./(400.0*1.1))):
     diffs = time[1:] - time[:-1]
     u = np.ones(len(time))
     v = np.ones(len(time))
     BLS = bls.eebls(time, lc, u, v, nf, fmin, df, nb, qmi, qma)
     f = fmin + (np.arange(len(BLS[0])))*df
     return BLS, 1/f, nb
Beispiel #3
0
def BLS(time, lc, df=0.0001, nf=500, nb=200, qmi=0.01, qma=0.8, fmin=(1.0 / (400.0 * 1.1))):

    u = numpy.ones(len(time))
    v = numpy.ones(len(time))

    BLS = bls.eebls(time, lc, u, v, nf, fmin, df, nb, qmi, qma)
    f = fmin + (numpy.arange(len(BLS[0]))) * df

    return BLS, 1 / f, nb
Beispiel #4
0
def process_lightcurve(lc, lc_duration):
    time = lc.times
    flux = lc.fluxes

    # Run this light curve through original FORTRAN implementation of BLS
    u = np.zeros_like(time)
    v = np.zeros_like(time)

    qmi = 0.25
    qma = lc_duration / 2

    results = bls.eebls(time, flux, u, v, nf, fmin, df, nb, qmi, qma)

    # Return results
    return results
Beispiel #5
0
def run_bls(file, nf=10000, a_logP = math.log(8000), b_logP = math.log(20000),
            nb=1500, qmi=0.0005, qma=0.005, verbose=True):
    if verbose:
        print "Reading data..."

    flux = np.loadtxt(file, delimiter=",")

    if verbose:
        print "Setting up arrays..."

    time = range(len(flux))
    n = len(flux)
    u = np.empty(n)
    v = np.empty(n)

    if verbose:
        print "Setting up BLS specs..."

    #Most of this are set through the function call, so I commented this out. For use later, perhaps.
    # Prior for period:
    min_period = math.exp(a_logP)
    max_period = math.exp(b_logP)

    ### Email Specs ####
    fmin = 1 / max_period
    fmax = 1 / min_period
    df = (fmax - fmin) / nf

    if verbose:
        print "EEBLS parameters:"
        print "nf=" + str(nf)
        print "fmin=" + str(fmin)
        print "fmax=" + str(fmax)
        print "df=" + str(df)
        print "nb=" + str(nb)
        print "qmi=" + str(qmi)
        print "qma=" + str(qma)
        print "Running EEBLS..."

    results = bls.eebls(time, flux, u, v, nf, fmin, df, nb, qmi, qma)
    #f = fmin + (np.arange(len(results[0])))*df

    if verbose:
        print "Done. Results:"
        print results

    return results
Beispiel #6
0
    def compute(self, verbose=True):
        """
        Compute using bls.eebls()
        """
        self.results = bls.eebls(self.t, self.f, self.u, self.v, self.nf,
                                 self.fmin, self.df, self.nb, self.qmi,
                                 self.qma)
        self._power = self.results[0]
        self._freq = self.fmin + np.arange(self.nf) * self.df
        self._best_period = self.results[1]
        self._best_freq = 1.0 / self._best_period
        self._best_power = self.results[2]
        self._depth = self.results[3]
        self._q = self.results[4]
        self._fraqdur = self.results[4]
        self._in1 = self.results[5]
        self._in2 = self.results[6]

        # Taking a look at https://github.com/dfm/python-bls/blob/master/ruth_bls2.py
        self._duration = self._best_period * self._q
        self._phase1 = self._in1 / float(self.nb)
        self._phase2 = self._in2 / float(self.nb)

        self._transit_number = int(
            (max(self.t) - min(self.t)) / self._best_period)
        self._epoch = self.t[
            0] + self._phase1 * self._best_period + self._duration / 2.
        self._ingresses = np.zeros(self._transit_number)
        self._egresses = np.zeros(self._transit_number)
        for n in range(0, self._transit_number):
            self._ingresses[n] = (self._epoch + self._best_period * n)  #- 0.2
            self._egresses[
                n] = self._epoch + self._best_period * n + self._duration  # + 0.2 # add a margin each side

        self._duration_approx = self._egresses[0] - self._ingresses[0]

        if verbose == True:
            print("=====Results====")
            print("Best period:", self._best_period)
            print("Best freq:", self._best_freq)
            print("Depth:", self._depth)
            print("Epoch:", self._epoch)
            print("Number of transits:", self._transit_number)
Beispiel #7
0
def BLS(time,
        mergedfluxD):  #time array, detrended flux arr (with transits injected)

    u = [0.0] * len(time)
    v = [0.0] * len(time)
    u = np.array(u)
    v = np.array(v)

    #time, flux, u, v, number of freq bins (nf), min freq to test (fmin), freq spacing (df), number of bins (nb), min transit dur (qmi), max transit dur (qma)

    nf = 1000.0
    fmin = .035
    df = 0.001
    nbins = 300
    qmi = 0.001
    qma = 0.3

    results = bls.eebls(time, mergedfluxD, u, v, nf, fmin, df, nbins, qmi, qma)

    #RESULTS:
    #power, best_period, best_power, depth, q, in1, in2
    #0      1            2           3      4  5    6

    SR_array = results[0]
    max_SR = max(SR_array)
    avg_SR = np.mean(SR_array)
    sd_SR = np.std(SR_array)
    #normaze SR_array between 0 and 1
    SR_array = [i / max_SR for i in SR_array]

    freq = fmin + np.arange(nf) * df

    #Signal Detection Efficiency
    SDE = (max_SR - avg_SR) / sd_SR

    #depth
    high = results[3] * results[4]
    low = high - results[3]
    fit = np.zeros(nbins) + high  # H
    fit[results[5]:results[6] + 1] = low  # L
    depth = high - low

    return results, SR_array, freq, SDE, depth
Beispiel #8
0
def blswrap(epicid, campaign, initial_time):
    global nbin
    try:
        start = time.time()
        initial_time = float(initial_time)
        t, f = data.retrieve(epicid, campaign, directory=directory)
        if initial_time != 0:
            t, f = t[t>initial_time], f[t>initial_time]
        u, v = np.zeros(len(t)), np.zeros(len(f))
        #minfreq, dfreq, nfreq = 1/70., 4.082799167108228e-06, 1000000
        minfreq, dfreq, nfreq = 0.015, 2.0437359493152146e-05,100000
        #nbin = 100
        minduration, maxduration = 0.01, 0.05
        results = bls.eebls(t, f, u, v, nfreq, minfreq, dfreq, nbin, minduration, maxduration)
        end = time.time()
        print(epicid, end - start)
        return epicid, results[1:]
    except:
        print("SKIPPING " + str(epicid))
Beispiel #9
0
def calc_bls(t, f, nf=10000, nb=1500, verbose=False, **bls_kwargs):
    """Main work-function, calculates the bls spectrum of an array.

    Uses EEBLS, programmed by Dan Foreman-Mackey, see:
    https://github.com/dfm/python-bls
    From the algorithm by Kovacs Zucker & Mazeh (2002)

    For a possible improvement, see:
    https://github.com/hpparvi/PyBLS

    Args:
        t (np.array-like): array of times
        f (np.array-like): array of fluxes (same len as t)
        nf (int):
        nb (int):
        verbose (bool): print information such as run-time
        **bls_kwargs: can contain qmi, qma, fmin, fmax etc...

    Returns:
        df_result, best_period, t0, duration, depth, (bls_output**)
            bls_result: pd.DataFrame with columns [f, period, power]
            bls_output**: the output values from the bls
                (power, best_period, best_power, depth,
                fractional_duration, in1, in2)

    Exceptions:
    """

    # This is a temporary fix and shouldn't be relied on
    if np.nanmedian(f) < 0.1:
        f = f - 1.0

    # Blocks the run if it would cause a FORTRAN error.
    if len(t) < 10:
        raise InvalidLightcurveError("Lightcurve has less then 10 points.")

    # Prepare parameters.
    # Observation duration:
    T = max(t) - min(t)
    assert T > 0		# Try to catch this earlier
    # Default frequency limits:
    fmax = 2.			# 12h period is minimum/maximum
    fmin = 2./T			# Require two transits currently
    # TODO: What happens if fmin is too low? Does BLS raise an error?
    # YES.

    # Unpack kwargs and replace the main values
    if 'qmi' in bls_kwargs.keys(): qmi = bls_kwargs['qmi']
    if 'qma' in bls_kwargs.keys(): qma = bls_kwargs['qma']
    if 'fmin' in bls_kwargs.keys(): fmin = bls_kwargs['fmin']
    if 'fmax' in bls_kwargs.keys(): fmax = bls_kwargs['fmax']

    # Frequency step.
    df = (fmax - fmin)/nf
    # Transit ratios/durations:
    qmi = (0.5/24)*fmin 	# assume half hour transit at minimum frequency
    qma = 0.1

    # Run checks on the parameters.
    # Skip all lightcurves that are less than 4 days currently.
    if T < min_light_curve:
        raise ShortLightcurveError("Skipping shortened lightcurve (T = {}).".format(T))
    # fmin must be greater than fmax.
    if fmin > fmax:
        raise ValueError("fmin > fmax - Observation period may be less than a day.")
    assert len(t) == len(f)
    # Period (1/fmin) greater than T
    if fmin < 1/T:
        raise InvalidLightcurveError("Max period (1/fmin) greater than"
                                    "lightcurve timescale.")

    # Run the BLS
    # -----------
    # The work arrays.
    u = np.empty(len(t), dtype=float)
    v = np.empty(len(t), dtype=float)

    start_time = time.time()
    power, best_period, best_power, depth, fractional_duration, in1, in2 = bls.eebls(t, f, u, v, nf, fmin, df, nb, qmi, qma)
    run_time = time.time() - start_time

    # Brief explanation of output:
    # ----------------------------
    # best_period is best-fit period in same units as time
    # best_power is the fit at best_period
    # depth is the depth of transit at best_period
    # in1 is the bin index at the start of the transit
    # in2 is the bin index at the end of transit

    if verbose:
        print("BLS running time: {}".format(run_time))

    # Package results.
    frequencies = fmin + np.arange(nf) * df
    periods = 1./frequencies
    assert len(frequencies) == len(power)
    df_result = pd.DataFrame({'frequency':frequencies, 'period':periods, 'power':power})

    # Convert in1 and in2 to t0 and duration perhaps
    duration = fractional_duration * best_period
    t0 = min(t) + best_period * (in1 + in2)/(2*nb)

    #tt0 = 0

    return df_result, best_period, t0, duration, depth, (power, best_period, best_power, depth, fractional_duration, in1, in2)
Beispiel #10
0
def calc_smart_bls(t, f, split_info=None, verbose=False, **split_kwargs):
    """Main work-function, calculates the bls spectrum of an array.

    Uses EEBLS, programmed by Dan Foreman-Mackey, see:
    https://github.com/dfm/python-bls
    From the algorithm by Kovacs Zucker & Mazeh (2002)

    For a possible improvement, see:
    https://github.com/hpparvi/PyBLS

    NOTE BUG: Current issue is that fractional_duration can be greater
              than the maximum fractional_duration (qma)

    Args:
        t (np.array-like): array of times
        f (np.array-like): array of fluxes (same len as t)
        split_info (pd.DataFrame): the information DataFrame
            controlling the runs. If not given, parameters must be
            input into split_kwargs
        verbose (bool): print information such as run-time, nf
        **split_kwargs: if split_info not given
            P_min, P_max, T, R_star, M_star, P_step,
            nf_tol, nb_tol, qms_tol

    Returns:
        bls_spectrum, best_period, t0, duration, depth, split_info
        bls_spectrum: pd.DataFrame with columns [frequency, period, power]
        split_info: the output values from the bls
                (best_period, best_power, depth,
                fractional_duration, in1, in2)

    Exceptions:
    """

    # This is a temporary fix and shouldn't be relied on
    if abs(np.nanmedian(f)) > 0.1:
        print("WARNING: f is not normalised with median at 0.0.",
              "Subtracting median. Median:", np.nanmedian(f))
        f = f - np.nanmedian(f)
    elif abs(np.nanmedian(f)) > 0.005:
        f = f - np.nanmedian(f)

    assert len(t) == len(f)

    # Prepare parameters
    # ------------------

    T = max(t) - min(t)
    if split_info is not None:
        split_info = split_info.copy()
    elif all(key in split_kwargs for key in ('R_star', 'M_star')):
        if 'P_min' not in split_kwargs:
            split_kwargs['P_min'] = 0.5
        if 'P_max' not in split_kwargs:
            split_kwargs['P_max'] = 0.5 + T/2

        split_info = get_split_info(T=T, **split_kwargs)
    else:
        raise ValueError("split_info not given, and split_kwargs doesn't "
                         "contain enough arguments: {}".format(split_kwargs))

    # Block the run if it would cause a FORTRAN error
    if len(t) < 10:
        raise InvalidLightcurveError("Lightcurve has less than 10 points.")

    if T < min_light_curve:
        raise ShortLightcurveError("Skipping shortened lightcurve "
                                   "(T = {}).".format(T))
    
    if (split_info.fmin < 1/T).any():
        raise InvalidLightcurveError("Max period (1/fmin) greater than "
                                    "lightcurve timescale for one of the "
                                    "splits.")

    if verbose:
        print("Total nf: {}\n".format(split_info.nf.sum()))

    # Perform the distributed BLS fitting
    # -----------------------------------

    # Holds the combined bls information
    bls_spectrum = pd.DataFrame(columns=['frequency', 'period', 'power'])

    for i in split_info.index:
        # The work arrays
        u = np.empty(len(t), dtype=float)
        v = np.empty(len(t), dtype=float)

        # Quick bullshit filter
        if split_info.loc[i, 'nf'] < 1:
            # TODO BUG: what to do here? make args None? Or what?
            # Will have to add a spectrum, if not a fake one
            # Ok, no spectrum addition needed
            print("negative nf")

        t_start = time.time()
        try:
            (power, best_period, best_power, depth,
            fractional_duration, in1, in2) = bls.eebls(
                                                t, f, u, v,
                                                nf=split_info.loc[i, 'nf'],
                                                fmin=split_info.loc[i, 'fmin'],
                                                df=split_info.loc[i, 'df'],
                                                nb=split_info.loc[i, 'nb'],
                                                qmi=split_info.loc[i, 'qmi'],
                                                qma=split_info.loc[i, 'qma'])
        except ValueError as e:
            print("ValueError when running bls.eebls.", split_info.loc[i])
            raise IntentValueError(
                "ValueError when running bls.eebls." + str(e),
                split_info.loc[i])
        t_end = time.time()

        split_info.loc[i, 'run_time'] = t_end - t_start
        split_info.loc[i, 'best_power'] = best_power
        split_info.loc[i, 'best_period'] = best_period
        split_info.loc[i, 'depth'] = depth
        split_info.loc[i, 'fractional_duration'] = fractional_duration
        split_info.loc[i, 'in1'] = in1
        split_info.loc[i, 'in2'] = in2

        # Package results
        frequencies = split_info.loc[i, 'fmin'] \
                + np.arange(split_info.loc[i, 'nf']) * split_info.loc[i, 'df']

        add_spectrum = pd.DataFrame({'frequency':frequencies,
                                     'period':1./frequencies,
                                     'power':power})

        bls_spectrum = bls_spectrum.append(add_spectrum, ignore_index=True)

    if verbose:
        print("Individual run times:", split_info.run_time)
        print("Total run time:", split_info.run_time.sum())

    # Order the total bls spectrum
    bls_spectrum.drop_duplicates(subset='frequency',
                                 keep='first',
                                 inplace=True)
    bls_spectrum.sort_values(by='frequency', inplace=True)
    bls_spectrum.index = range(len(bls_spectrum))

    # Select the strongest peak across the stitched spectrum
    imax = split_info.best_power.idxmax()

    best_period = split_info.loc[imax, 'best_period']
    best_power = split_info.loc[imax, 'best_power']
    depth = split_info.loc[imax, 'depth']
    fractional_duration = split_info.loc[imax, 'fractional_duration']
    in1 = split_info.loc[imax, 'in1']
    in2 = split_info.loc[imax, 'in2']
    nb = split_info.loc[imax, 'nb']

    # in1 is the bin index at the start of the transit
    # in2 is the bin index at the end of transit

    # Convert in1 and in2 to t0 and duration
    duration = fractional_duration * best_period
    t0 = min(t) + best_period * (in1 + in2)/(2*nb)

    # TODO: turn this into an automatic discarding of any 25% duration
    # dips **in split_info**, so that it never removes such a large fraction
    if fractional_duration >= 0.25:
        pd.set_option('display.max_rows', 10)
        pd.set_option('display.max_columns', 20)
        print(split_info, "\nduration = {}".format(fractional_duration),
              "\nsplit_kwargs = {}".format(split_kwargs))

    return (bls_spectrum, best_period, best_power,
            t0, duration, depth, split_info)
def get_period(t, f_t, outputpath='', starname=''):

    # here we use a BLS algorithm to create a periodogram and find the best periods. The BLS is implemented in Python by Ruth Angus and Dan Foreman-Mackey

    outputfolder = os.path.join(outputpath, str(starname))
    fmin = 2.0 / (
        (t[len(t) - 1] - t[0])
    )  # minimum frequency. we can't find anything longer than 90 days obviously
    nf = 3e6  # amount of frequencies to try
    df = 1e-5  #0.00001 # frequency step

    qmi = 0.0005  # min relative length of transit (in phase unit)
    qma = 0.1  # max relative length of transit (in phase unit)
    nb = 200  # number of bins in folded LC

    u = np.linspace(fmin, fmin + nf * df, nf)
    v = np.array(0)
    t = np.array(t)
    f_t = np.array(f_t)

    t_orig = np.copy(t)
    f_t_orig = f_t

    results = bls.eebls(t, f_t, t, f_t, nf, fmin, df, nb, qmi, qma)
    freqlist = u
    powers = results[0]
    period = results[1]
    #print(results[2], results[3])
    depth = results[2]
    duration = results[3]

    folded, f_t_folded = fold_data(t, f_t, period)

    try:
        np.savetxt(os.path.join(outputfolder, 'Flattened.txt'),
                   np.transpose([t, f_t]),
                   header='Time, Flux')
        np.savetxt(os.path.join(outputfolder, 'PhaseFolded.txt'),
                   np.transpose([folded, f_t_folded]),
                   header='Time, Flux')
        np.savetxt(os.path.join(outputfolder, 'OptimalDepth.txt'), [depth],
                   header='Depth')
        np.savetxt(os.path.join(outputfolder, 'OptimalDuration.txt'),
                   [duration],
                   header='Fractional Duration')
    except:
        os.mkdir(outputfolder)
        np.savetxt(os.path.join(outputfolder, 'Flattened.txt'),
                   np.transpose([t, f_t]),
                   header='Time, Flux')
        np.savetxt(os.path.join(outputfolder, 'PhaseFolded.txt'),
                   np.transpose([folded, f_t_folded]),
                   header='Time, Flux')
        np.savetxt(os.path.join(outputfolder, 'OptimalDepth.txt'), [depth],
                   header='Depth')
        np.savetxt(os.path.join(outputfolder, 'OptimalDuration.txt'),
                   [duration],
                   header='Fractional Duration')

    t_foldbin, f_t_foldbin, stdv_foldbin = rebin_dataset(
        folded, f_t_folded, 15)
    f_t_smooth = savitzky_golay(f_t_folded, 101, 1)

    # unravel again
    n_start = int(np.round(t[0] / period))
    n_end = np.round(t[-1] / period) + 1
    i = n_start

    t_unravel = []
    f_t_unravel = []
    while i < n_end:
        t_unravel.append(np.array(folded) + i * period + t_orig[0])
        f_t_unravel.append(np.array(f_t_smooth))

        #pl.plot(t_unravel[i],f_t_unravel[i],color='black',lw='1.5')
        i = i + 1

    if abs(period - 0.24) < 0.01:
        freqlist, powers = maskout_freqs(freqlist, powers,
                                         freq=0.245)  # spacecraft freqs
        Location = np.where(powers == max(powers))
        period = freqlist[Location[0]][0]
    print("The best period is: ", period)
    return folded, f_t_folded, period, freqlist, powers
def get_period(t,f_t,get_mandelagolmodel=True,outputpath='',starname=''):
  #
  # here we use a BLS algorithm to create a periodogram and find the best periods. The BLS is implemented in Python by Ruth Angus and Dan Foreman-Macey
  #

  outputfolder = os.path.join(outputpath,str(starname))

  fmin = 0.03 # minimum frequency. we can't find anything longer than 90 days obviously
  nf = 60000 # amount of frequencies to try
  df = 0.00001 # frequency step

  qmi = 0.0005 # min relative length of transit (in phase unit)
  qma = 0.1 # max relative length of transit (in phase unit)
  nb = 200 # number of bins in folded LC

  u = np.linspace(fmin,fmin + nf*df,nf)
  v = np.array(0)
  t = np.array(t)
  print t[0]
  f_t = np.array(f_t)

  t_orig = np.copy(t)
  f_t_orig = f_t
  results = bls.eebls(t,f_t,t,f_t,nf,fmin,df,nb,qmi,qma)
  freqlist = u
  powers = results[0]
  period = results[1]

  folded,f_t_folded = fold_data(t,f_t,period)

  np.savetxt(os.path.join(outputfolder, 'folded_P' + str(period) + 'star_' + str(starname) + '.txt'),np.transpose([folded,f_t_folded]),header='Time, Flux')

  t_foldbin,f_t_foldbin,stdv_foldbin = rebin_dataset(folded,f_t_folded,15)
  f_t_smooth = savitzky_golay(f_t_folded,29,1)
  pl.figure('my data folded bls')
  pl.plot(folded,f_t_folded+1.,'.',color='black',label='K2 photometry')
  pl.xlabel('Time [d]')
  pl.ylabel('Relative Flux')

  if get_mandelagolmodel:
    # this is not a core part of the module and uses a transit model by Mandel & Agol, implemented in Python by Ian Crossfield.

    #[T0,b,R_over_a,Rp_over_Rstar,flux_star,gamma1,gamma2]
    transit_params = np.array([4.11176,0.9,0.104,np.sqrt(0.0036),1.,0.2,0.2])
    import model_transits
    times_full = np.linspace(0.,period,10000)
    model = model_transits.modeltransit(transit_params,model_transits.occultquad,period,times_full)

    pl.figure('Transit model')
    pl.scatter((folded-transit_params[0])*24.,f_t_folded+1.,color='black',label='K2 photometry',s=10.)

    pl.plot((times_full-transit_params[0])*24.,model,color='grey',lw=4,label='Transit model')
    pl.xlabel('Time from mid-transit [hr]',fontsize=17)
    pl.ylabel('Relative flux',fontsize=17)
    legend = pl.legend(loc='upper center',numpoints=1,scatterpoints=1,fontsize=15,prop={'size':15},title='EPIC 205071984')
    pl.tick_params(labelsize=17)
    pl.tick_params(axis='both', which='major', width=1.5)

    pl.tight_layout()
    pl.setp(legend.get_title(),fontsize=17)
  pl.savefig(os.path.join(outputfolder, 'folded_P_' + 'star_' + str(starname) +str(period) + '.png'))

  # unravel again
  n_start = int(np.round(t[0] / period))
  n_end = np.round(t[-1] / period) + 1
  i = n_start
  pl.figure()
  pl.plot(t_orig,f_t,'*')

  t_unravel = []
  f_t_unravel = []
  while i < n_end:
    t_unravel.append(np.array(folded) + i*period + t_orig[0])
    f_t_unravel.append(np.array(f_t_smooth))

    pl.plot(t_unravel[i],f_t_unravel[i],color='black',lw='1.5')
    i = i + 1

  print 'best period is '
  print period

  return folded,f_t_folded,period,freqlist,powers
Beispiel #13
0
def getBLS(lc, TIC, filename, t0=0, multirunthresh=5.):
    '''Runs BLS search for transits on lightcurve.
    Returns 3-column array (detns) with the position and height of any peaks, and the 2-column spectrum'''

    #Using custom timerange across full lightcurve/1.1 to 0.4d
    min_freq = 1.1 / (lc[-1, 0] - lc[0, 0])
    max_freq = 1. / 0.4
    freq_spacing = 1e-5
    nfb = int(np.floor((max_freq - min_freq) / freq_spacing))
    nb = 400

    count = 0
    while True:

        #remove transit for all but first run
        if count > 0:
            lccut = CutTransits(lccut, epoch, bper, phase1, phase2)
        else:
            lccut = lc.copy()

        powOut = bls.eebls(lccut[:, 0],
                           lccut[:, 1],
                           np.zeros(len(lccut[:, 0])),
                           np.zeros(len(lccut[:, 0])),
                           nfb,
                           fmin=min_freq,
                           df=freq_spacing,
                           nb=nb,
                           qmi=0.005,
                           qma=0.15)
        PowArr = np.column_stack(
            (1 /
             (np.arange(min_freq,
                        (min_freq + nfb * freq_spacing), freq_spacing))[0:nfb],
             powOut[0]))
        PowArr = PowArr[PowArr[:, 0].argsort(), :]

        #Rescaling both BLS and LS such that the median (of values <0.3*the max value ) is at 1 and the position of a peak gives the height above the median
        PowArr[:, 1] = PowArr[:, 1] / np.median(
            PowArr[:, 1][PowArr[:, 1] < np.percentile(PowArr[:, 1], 95)])
        if count == 0:
            blsoutfile = filename[:-4] + '_' + str(TIC) + '_' + str(
                count
            ) + '_pgram.txt'  #includes count in case we want to save the others later
            np.savetxt(blsoutfile, PowArr)

        detnsOut_lccut = getPeaks(PowArr)
        detnsOut_lccut = detnsOut_lccut[(-detnsOut_lccut[:, 1]).argsort(), :]
        detnsOut_lccut = np.hstack(
            (detnsOut_lccut, np.ones([len(detnsOut_lccut[:, 0]), 1]) + count))

        detnmax = np.max(detnsOut_lccut[:, 2])

        bper = powOut[1]
        bpow = powOut[2]
        depth = powOut[3]
        qtran = powOut[4]
        duration = bper * qtran
        in1 = powOut[5]
        in2 = powOut[6]
        phase1 = in1 / float(nb)
        phase2 = in2 / float(nb)
        epoch = lccut[0, 0]

        epoch_array = np.zeros([
            len(detnsOut_lccut[:, 0]), 1
        ])  #hard to easily extract epoch etc for more than just main peak
        epoch_array[0] = (epoch + phase1 * bper) + t0

        #check if only one transit in middle of lc
        if epoch + (phase1 + 1) * bper > lccut[-1, 0]:
            detnmax = multirunthresh + 1  #force another run, unless we hit max via count
            detnsOut_lccut[0, 0] = -10.  #set peak period to -10

        if count == 0:
            detnsOut = np.hstack((detnsOut_lccut, epoch_array))
        else:
            detnsOut = np.vstack(
                (detnsOut, np.hstack((detnsOut_lccut, epoch_array))))

        count += 1

        if detnmax < multirunthresh:
            break

        if count > 2:
            break

    return detnsOut
Beispiel #14
0
    u = [0.0] * len(time)
    v = [0.0] * len(time)
    u = np.array(u)
    v = np.array(v)

    #time, flux, u, v, number of freq bins (nf), min freq to test (fmin), freq spacing (df), number of bins (nb), min transit dur (qmi), max transit dur (qma)

    nf = 1000.0
    fmin = .035
    df = 0.001
    nbins = 300
    qmi = 0.001
    qma = 0.3

    results = bls.eebls(time, mergedfluxDetrend, u, v, nf, fmin, df, nbins,
                        qmi, qma)

    #RESULTS:
    #power, best_period, best_power, depth, q, in1, in2
    #0      1            2           3      4  5    6

    print('DEPTH: ' + str(results[3]))

    print('BLS period: ' + str(results[1]))

    ###################################################################################

    SR_array = results[0]
    max_SR = max(SR_array)
    avg_SR = np.mean(SR_array)
    sd_SR = np.std(SR_array)
    def compute(self):
        time = self.target.light_curve.time
        flux = self.target.light_curve.flux
        ferr = self.target.light_curve.ferr

        u = np.ones(len(time))
        v = np.ones(len(time))
        nf = 50
        fmin = 1 / (time[-1] - time[0]) * 1.01
        df = 0.00541570
        nb = 50
        qmi = 0.01000
        qma = 0.10000

        self.f = fmin + np.arange(nf) * df
        f_1 = 1/self.f

        results = bls.eebls(time, flux, u, v, nf, fmin, df, nb, qmi, qma)
        self.power = results[0]
        self.best_period = results[1]
        self.best_power = results[2]
        self.depth = results[3]
        q = results[4]
        in1 = results[5]
        in2 = results[6]

        ## Mimic what the python-bls demo code does to get all the information we need to calculate system parameters

        # Compute duration
        self.duration = self.best_period * q
        phase1 = in1 / float(nb)
        phase2 = in2 / float(nb)

        # Find peaks
        convolved_bls = scipy.ndimage.filters.gaussian_filter(self.power, 2.0)
        peak = np.r_[True, convolved_bls[1:] > convolved_bls[:-1]] & np.r_[convolved_bls[:-1] > convolved_bls[1:], True]
        sel_peaks = np.sort(convolved_bls[peak])
        sel_peaks = sel_peaks[-1:]
        self.all_periods = f_1[np.where(convolved_bls == sel_peaks)]

        # Calculate # of transits, epoch, ingress ,egress times
        t_number = int((np.max(time) - np.min(time)) / self.best_period)
        self.epoch = time[0] + phase1 * self.best_period

        ingresses = np.zeros(t_number)
        egresses = np.zeros(t_number)
        for n in xrange(0, t_number):
            # Compute w/ a margin on each side
            ingresses[n] = (self.epoch + self.best_period * n) - 0.2
            egresses[n] = self.epoch + self.best_period*n + self.duration + 0.2
        self.ingresses = ingresses
        self.egresses = egresses
        self.approx_duration = egresses[0] - ingresses[0]

        # Stuff only useful for sample calculation
        self.values = {
            'in1': in1,
            'phase1': phase1,
            'nb': nb,
            'q': q
        }
def get_BLS_2 (time, flux, starname, outputfolder, Pmin, Pmax, nP, qmin, qmax, nb):
    """
    Find Box-fitting Least Squares (BLS) frequency spectrum.
    
    Input:
    time = array containing data points of the time series
    flux = array containing data points of the flux series
    Pmin = minimal oribtal period
    Pmax = maximal orbital period
    nP = number of oribtal periods to compute
    qmin = minimal fractional transit length (duration = q * period)
    qmax = maximal fractional transit length
    nb = number of bins in which the data should be binned
    
    Output:
    BLS = BLS frequency spectrum
    P = array containing periods
    best_params = parameters of interest correpsonding to the maximal value in 
    the BLS and two candidate periods ([period, power, fractional transit length, 
    transitdepth, transitcenter])
    """
    
    # calculate the weight for all datapoints
    flux = flux - np.median(flux) # make average signal zero
    P = np.linspace(Pmin,Pmax,nP)
    nf = nP
    fmin = 1./Pmax
    fmax = 1./Pmin
    df = np.diff(P)[0]
    u = np.linspace(fmin,fmin + nf*df,nf)
    v = np.linspace(fmin,fmin + nf*df,nf)
    
    # best period parameters
    results = bls.eebls(time, flux, time, flux, nf, fmin, df, nb, qmin, qmax)
    BLS, best_period, best_power, depth, q, in1, in2 = results
    P = 1./u
    time_f, flux_f = fold_data(time, flux, best_period) # Pbest
    time_f_b = bin_data(time_f, nb, median = False)
    flux_f_b = bin_data(flux_f, nb, median = False)
    center = time_f_b[np.argmin(flux_f_b)]
    params_Pbest = np.array([best_period, best_power, q, depth, center])
    
    # get best three periods and other relevant parameters
    Pbest, P2, P3, best_power_Pbest, best_power_P2, best_power_P3 = find_candidate_periods_2(P, BLS)
    
    time_f, flux_f = fold_data(time, flux, P2) # P2
    time_f_b = bin_data(time_f, nb, median = False)
    flux_f_b = bin_data(flux_f, nb, median = False)
    center = time_f_b[np.argmin(flux_f_b)]
    depth = np.min(flux_f_b)
    params_P2 = np.array([P2, best_power_P2, q, depth, center])
    
    time_f, flux_f = fold_data(time, flux, P3) # P3
    time_f_b = bin_data(time_f, nb, median = False)
    flux_f_b = bin_data(flux_f, nb, median = False)
    center = time_f_b[np.argmin(flux_f_b)]
    depth = np.min(flux_f_b)
    params_P3 = np.array([P3, best_power_P3, q, depth, center])
    
    # combine all the parameters
    params = np.vstack((params_Pbest, params_P2, params_P3))
    
    # save as txt file
    data = np.array(zip(P, BLS))
    data_header = '#0 period, 1 SR'
    np.savetxt(os.path.join(outputfolder,'bls_' 
               + str(starname) + '.txt'), data, header=data_header, fmt='%s')
    data = np.copy(params)
    data_header = '#0 best period 1 corresponding SR 2 q 3 transitdepth 4 index at start of transit 5 index at end of transit'
    np.savetxt(os.path.join(outputfolder,'blsparams_' 
               + str(starname) + '.txt'), data, header=data_header, fmt='%s')
               
    # Calculate Signal Detection Efficiency value for best period
    SRbest = params[0,1]
    SDE = (SRbest - np.mean(BLS) )/np.std(BLS)
    
    return P, BLS, params, Pbest, SDE
Beispiel #17
0
def main(rad_min, rad_max, rad_step, per_min, per_max, per_step):

    detect_count = 0
    detect_SDE = []*18905
    detect_per = []*18905
    detect_rad = []*18905
    detect_BLS_per = []*18905

    undetect_count = 0
    undetect_SDE = []*18905
    undetect_per = []*18905
    undetect_rad = []*18905

    detect_diff = []*18905
    undetect_diff = []*18905

    diff = [[0 for x in range(96)] for y in range(200)]
    
    #Limits and step size can be changed
    rad_range = numpy.arange(rad_min, rad_max, rad_step)
    per_range = numpy.arange(per_min, per_max, per_step)

    rindex = -1
    pindex = -1

    for r in rad_range:
        rindex += 1
        pindex = 0
        for p in per_range:
            pindex += 1

        
            currentdir = makedir("/Users/sheilasagear/OneDrive/K2_Research/bls-ktransit/Pipeline/EPIC229227250-2sigclip", r, p)

            time, flux = importLC('/Users/sheilasagear/OneDrive/K2_Research/Corrected Light Curve by EPIC ID (.txt)/hlsp_k2sff_k2_lightcurve_229227254-c06_kepler_v1_llc-default-aper.txt')

            flux = sigma_clip(flux, sigma=2, iters=1)

            ktflux = createktransit(time, p, r)
            
            savektransitLC(currentdir, time, ktflux, p, r)

            merged_flux = injecttransit(ktflux, flux)

            savemergedLC(currentdir, "EPICX", time, merged_flux, p, r)

        ##########################
        #BLS routine
        ##########################

            u = [0.0]*len(time)
            v = [0.0]*len(time)

            u = numpy.array(u)
            v = numpy.array(v)

            nbins = 200
        
            results = bls.eebls(time, merged_flux, u, v, 1000.0, .3, .001, nbins, .001, .3)


#RESULTS:
#power, best_period, best_power, depth, q, in1, in2
#0      1            2           3      4  5    6

            print('Planet radius/star radius:' + str(r))
            print('Period from BLS is: ' + str(results[1]))
            print('Set period is: ' + str(p))
        

            max_SR, avg_SR, sd_SR = saveSRplot(currentdir, 'EPICX', results[0], p, r)

        
            SDE, detect_count, detect_SDE, detect_per, detect_rad, detect_BLS_per, detect_diff, undetect_count, undetect_SDE, undetect_per, undetect_rad, undetect_diff = SDEcount(max_SR, avg_SR, sd_SR, p, r, detect_count, detect_SDE, detect_per, detect_rad, detect_BLS_per, detect_diff, undetect_count, undetect_SDE, undetect_per, undetect_rad, undetect_diff, results[1])


            savefoldbin(currentdir, SDE, time, nbins, results[1], results[3], results[4], results[5], results[6], u, v, p, r)

        ##########################
        #END LOOP
        ##########################


    savetext('/Users/sheilasagear/OneDrive/K2_Research/bls-ktransit/SDE_text/data213244700.txt', detect_diff, detect_SDE, detect_BLS_per, detect_per, detect_rad)

#deletes extras from arrays

    for i in range(len(detect_SDE)):
        if detect_SDE[i] == 0:
            del detect_SDE[i]

    for i in range(len(detect_per)):
        if detect_per[i] == 0:
            del detect_per[i]

    for i in range(len(detect_rad)):
        if detect_rad[i] == 0:
            del detect_rad[i]

    for i in range(len(undetect_SDE)):
        if undetect_SDE[i] == 0:
            del undetect_SDE[i]

    for i in range(len(undetect_per)):
        if undetect_per[i] == 0:
            del undetect_per[i]
            
    for i in range(len(undetect_rad)):
        if undetect_rad[i] == 0:
            del undetect_rad[i]


    showinitialLC(time, flux)

    show2Dscatter(detect_per, detect_rad, rad_max, per_max)

    show3Dscatter(detect_per, detect_rad, detect_diff, detect_SDE)
Beispiel #18
0
def process_lightcurve(lc: LightcurveArbitraryRaster, lc_duration: float,
                       search_settings: dict):
    """
    Perform a transit search on a light curve, using the bls_kovacs code.

    :param lc:
        The lightcurve object containing the input lightcurve.
    :type lc:
        LightcurveArbitraryRaster
    :param lc_duration:
        The duration of the lightcurve, in units of days.
    :type lc_duration:
        float
    :param search_settings:
        Dictionary of settings which control how we search for transits.
    :type search_settings:
        dict
    :return:
        dict containing the results of the transit search.
    """

    time = lc.times  # Unit of days
    flux = lc.fluxes

    # Median subtract lightcurve
    median = np.median(flux)
    flux -= median

    # Run this light curve through original FORTRAN implementation of BLS
    u = np.zeros(len(time))
    v = np.zeros(len(time))

    # Minimum transit length
    qmi = 0.05

    # Maximum transit length
    qma = 0.2

    # Minimum transit period, days
    minimum_period = float(search_settings.get('period_min', 0.5))
    fmax = 1 / minimum_period

    # Maximum transit period, seconds
    # Arithmetic here based on <https://docs.astropy.org/en/stable/api/astropy.timeseries.BoxLeastSquares.html#astropy.timeseries.BoxLeastSquares.autoperiod>
    minimum_n_transits = 2
    maximum_period = float(
        search_settings.get('period_max', lc_duration / minimum_n_transits))
    fmin = 1 / maximum_period

    # Frequency spacing
    frequency_factor = 2
    df = frequency_factor * qmi / lc_duration**2
    nf = (fmax - fmin) / df

    # Number of bins (maximum 2000)
    # For large number of bins, the FORTRAN code seems to segfault, which limits usefulness of this code
    # See issue described here <https://github.com/dfm/python-bls/issues/4>
    nb = 10

    # results = {}
    results = bls.eebls(time, flux, u, v, nf, fmin, df, nb, qmi, qma)

    # Unpack results
    power, best_period, best_power, depth, q, in1, in2 = results

    results = {"period": best_period, "power": best_power, "depth": depth}

    # Extended results to save to disk
    results_extended = results

    # Return results
    return results, results_extended
Beispiel #19
0
    u = [0.0] * len(time)
    v = [0.0] * len(time)

    u = np.array(u)
    v = np.array(v)

    #time, flux, u, v, number of freq bins (nf), min freq to test (fmin), freq spacing (df), number of bins (nb), min transit dur (qmi), max transit dur (qma)

    nf = 1000.0
    fmin = .02
    df = 0.001
    nbins = 700
    qmi = 0.001
    qma = 0.3

    results = bls.eebls(time, flux, u, v, nf, fmin, df, nbins, qmi, qma)

    #RESULTS:
    #power, best_period, best_power, depth, q, in1, in2
    #0      1            2           3      4  5    6

    print('BLS period: ' + str(results[1]))

    SR_array = results[0]
    max_SR = max(SR_array)
    avg_SR = np.mean(SR_array)
    sd_SR = np.std(SR_array)

    #normalize SR_array between 0 and 1
    SR_array = [i / max_SR for i in SR_array]
Beispiel #20
0
            #plt.show(merged_LC)


##########################
#BLS routine
##########################

            u = [0.0]*len(time)
            v = [0.0]*len(time)

            u = np.array(u)
            v = np.array(v)

            nbins = 200
        
            results = bls.eebls(time, merged_flux, u, v, 1000.0, .3, .001, nbins, .001, .3)

#RESULTS:
#power, best_period, best_power, depth, q, in1, in2
#0      1            2           3      4  5    6

            print('Planet radius/star radius:' + str(r))
            print('Period from BLS is: ' + str(results[1]))
            print('Set period is: ' + str(p))
        
##########################
#SR plot
##########################

            SR_array = results[0]
Beispiel #21
0
        pylab.savefig("/Users/sheilasagear/OneDrive/K2_Research/bls-ktransit/LC_5/Period" + str(p) + "Radius" + str(r) + "/merged_fluxPer" + str(p) + "Rad" + str(r) + '.png')
        """

        #plt.show(merged_LC)

        ##########################
        #BLS routine
        ##########################

        u = [0.0] * len(time)
        v = [0.0] * len(time)

        u = numpy.array(u)
        v = numpy.array(v)

        results = bls.eebls(time, merged_flux, u, v, 1000.0, .3, .001, 500.0,
                            .01, .1)

        #print(results)

        #RESULTS:
        #power, best_period, best_power, depth, q, in1, in2
        #0      1            2           3      4  5    6

        print('Planet radius/star radius:' + str(r))
        print('Period from BLS is: ' + str(results[1]))
        print('Set period is: ' + str(p))

        ##########################
        #SR plot
        ##########################
Beispiel #22
0
    ##########################

    u = [0.0] * len(time)
    v = [0.0] * len(flux)

    u = np.array(u)
    v = np.array(v)

    nf = 1000.0
    fmin = .035
    df = 0.001
    nb = 300
    qmi = 0.001
    qma = 0.3

    results = bls.eebls(time, merged_flux, u, v, nf, fmin, df, nb, qmi, qma)

    #RESULTS:
    #power, best_period, best_power, depth, q, in1, in2
    #0      1            2           3      4  5    6

    print('BLS period: ' + str(results[1]))

    ##########################
    #Power Spectrum
    ##########################

    SR_array = results[0]
    max_SR = max(SR_array)
    avg_SR = np.mean(SR_array)
    sd_SR = np.std(SR_array)