<EOL>if (npeaks and (<NUM_LIT:0> < npeaks < len(blsdict['<STR_LIT>']))):<EOL><INDENT>nperiods = npeaks<EOL><DEDENT>else:<EOL><INDENT>if verbose:<EOL><INDENT>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>len(blsdict['<STR_LIT>']))<EOL><DEDENT>nperiods = len(blsdict['<STR_LIT>'])<EOL><DEDENT>nbestperiods = blsdict['<STR_LIT>'][:nperiods]<EOL>stimes, smags, serrs = sigclip_magseries(times,<EOL>mags,<EOL>errs,<EOL>magsarefluxes=magsarefluxes,<EOL>sigclip=sigclip)<EOL>if len(stimes) > <NUM_LIT:9> and len(smags) > <NUM_LIT:9> and len(serrs) > <NUM_LIT:9>:<EOL><INDENT>nbestsnrs = []<EOL>transitdepth, transitduration = [], []<EOL>nphasebins, transingressbin, transegressbin = [], [], []<EOL>allsubtractedmags = []<EOL>allphasedmags = []<EOL>allphases = []<EOL>allblsmodels = []<EOL>refitperiods = []<EOL>refitepochs = []<EOL>for period in nbestperiods:<EOL><INDENT>startp = period - perioddeltapercent*period/<NUM_LIT><EOL>if startp < <NUM_LIT:0>:<EOL><INDENT>startp = period<EOL><DEDENT>endp = period + perioddeltapercent*period/<NUM_LIT><EOL>if not assumeserialbls:<EOL><INDENT>prevkwargs = blsdict['<STR_LIT>'].copy()<EOL>prevkwargs['<STR_LIT>'] = verbose<EOL>prevkwargs['<STR_LIT>'] = startp<EOL>prevkwargs['<STR_LIT>'] = endp<EOL>prevkwargs['<STR_LIT>'] = None<EOL>blsres = bls_serial_pfind(stimes,<EOL>smags,<EOL>serrs,<EOL>**prevkwargs)<EOL><DEDENT>else:<EOL><INDENT>blsres = blsdict<EOL><DEDENT>thistransdepth = blsres['<STR_LIT>']['<STR_LIT>']<EOL>thistransduration = blsres['<STR_LIT>']['<STR_LIT>']<EOL>thisbestperiod = blsres['<STR_LIT>']<EOL>thistransingressbin = blsres['<STR_LIT>']['<STR_LIT>']<EOL>thistransegressbin = blsres['<STR_LIT>']['<STR_LIT>']<EOL>thisnphasebins = blsdict['<STR_LIT>']['<STR_LIT>']<EOL>stats = _get_bls_stats(stimes,<EOL>smags,<EOL>serrs,<EOL>thistransdepth,<EOL>thistransduration,<EOL>ingressdurationfraction,<EOL>nphasebins,<EOL>thistransingressbin,<EOL>thistransegressbin,<EOL>thisbestperiod,<EOL>thisnphasebins,<EOL>magsarefluxes=magsarefluxes,<EOL>verbose=verbose)<EOL>nbestsnrs.append(stats['<STR_LIT>'])<EOL>transitdepth.append(stats['<STR_LIT>'])<EOL>transitduration.append(stats['<STR_LIT>'])<EOL>transingressbin.append(stats['<STR_LIT>'])<EOL>transegressbin.append(stats['<STR_LIT>'])<EOL>nphasebins.append(stats['<STR_LIT>'])<EOL>refitperiods.append(stats['<STR_LIT>'])<EOL>refitepochs.append(stats['<STR_LIT>'])<EOL>allsubtractedmags.append(stats['<STR_LIT>'])<EOL>allphasedmags.append(stats['<STR_LIT>'])<EOL>allphases.append(stats['<STR_LIT>'])<EOL>allblsmodels.append(stats['<STR_LIT>'])<EOL><DEDENT><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>')<EOL>nbestsnrs = None<EOL>transitdepth, transitduration = None, None<EOL>nphasebins, transingressbin, transegressbin = None, None, None<EOL>allsubtractedmags, allphases, allphasedmags = None, None, None<EOL><DEDENT>return {'<STR_LIT>':npeaks,<EOL>'<STR_LIT>':refitperiods,<EOL>'<STR_LIT>':refitepochs,<EOL>'<STR_LIT>':nbestsnrs,<EOL>'<STR_LIT>':transitdepth,<EOL>'<STR_LIT>':transitduration,<EOL>'<STR_LIT>':nphasebins,<EOL>'<STR_LIT>':transingressbin,<EOL>'<STR_LIT>':transegressbin,<EOL>'<STR_LIT>':allblsmodels,<EOL>'<STR_LIT>':allsubtractedmags,<EOL>'<STR_LIT>':allphasedmags,<EOL>'<STR_LIT>':allphases}<EOL>

Calculates the signal to noise ratio for each best peak in the BLS
    periodogram, along with transit depth, duration, and refit period and epoch.

    The following equation is used for SNR::

        SNR = (transit model depth / RMS of LC with transit model subtracted)
              * sqrt(number of points in transit)

    Parameters
    ----------

    blsdict : dict
        This is an lspinfo dict produced by either `bls_parallel_pfind` or
        `bls_serial_pfind` in this module, or by your own BLS function. If you
        provide results in a dict from an external BLS function, make sure this
        matches the form below::

            {'bestperiod': the best period value in the periodogram,
             'bestlspval': the periodogram peak associated with the best period,
             'nbestpeaks': the input value of nbestpeaks,
             'nbestlspvals': nbestpeaks-size list of best period peak values,
             'nbestperiods': nbestpeaks-size list of best periods,
             'lspvals': the full array of periodogram powers,
             'frequencies': the full array of frequencies considered,
             'periods': the full array of periods considered,
             'blsresult': list of result dicts from eebls.f wrapper functions,
             'stepsize': the actual stepsize used,
             'nfreq': the actual nfreq used,
             'nphasebins': the actual nphasebins used,
             'mintransitduration': the input mintransitduration,
             'maxtransitduration': the input maxtransitdurations,
             'method':'bls' -> the name of the period-finder method,
             'kwargs':{ dict of all of the input kwargs for record-keeping}}

    times,mags,errs : np.array
        These contain the magnitude/flux time-series and any associated errors.

    assumeserialbls : bool
        If this is True, this function will not rerun BLS around each best peak
        in the input lspinfo dict to refit the periods and epochs. This is
        usally required for `bls_parallel_pfind` so set this to False if you use
        results from that function. The parallel method breaks up the frequency
        space into chunks for speed, and the results may not exactly match those
        from a regular BLS run.

    magsarefluxes : bool
        Set to True if the input measurements in `mags` are actually fluxes and
        not magnitudes.

    npeaks : int or None
        This controls how many of the periods in `blsdict['nbestperiods']` to
        find the SNR for. If it's None, then this will calculate the SNR for all
        of them. If it's an integer between 1 and
        `len(blsdict['nbestperiods'])`, will calculate for only the specified
        number of peak periods, starting from the best period.

    perioddeltapercent : float
        The fraction of the period provided to use to search around this
        value. This is a percentage. The period range searched will then be::

            [period - (perioddeltapercent/100.0)*period,
             period + (perioddeltapercent/100.0)*period]

    ingressdurationfraction : float
        The fraction of the transit duration to use to generate an initial value
        of the transit ingress duration for the BLS model refit. This will be
        fit by this function.

    verbose : bool
        If True, will indicate progress and any problems encountered.

    Returns
    -------

    dict
        A dict of the following form is returned::

            {'npeaks: the number of periodogram peaks requested to get SNR for,
             'period': list of refit best periods for each requested peak,
             'epoch': list of refit epochs (i.e. mid-transit times),
             'snr':list of SNRs of the transit for each requested peak,
             'transitdepth':list of depths of the transits,
             'transitduration':list of durations of the transits,
             'nphasebins':the input value of nphasebins,
             'transingressbin':the phase bin containing transit ingress,
             'transegressbin':the phase bin containing transit egress,
             'allblsmodels':the full BLS models used along with its parameters,
             'allsubtractedmags':BLS models - phased light curves,
             'allphasedmags':the phase light curves,
             'allphases': the phase values}


baseline = times.max() - times.min()<EOL>nsamples = times.size<EOL>df = <NUM_LIT:1.> / baseline / samplesperpeak<EOL>if minfreq is not None:<EOL><INDENT>f0 = minfreq<EOL><DEDENT>else:<EOL><INDENT>f0 = <NUM_LIT:0.5> * df<EOL><DEDENT>if maxfreq is not None:<EOL><INDENT>Nf = int(np.ceil((maxfreq - f0) / df))<EOL><DEDENT>else:<EOL><INDENT>Nf = int(<NUM_LIT:0.5> * samplesperpeak * nyquistfactor * nsamples)<EOL><DEDENT>if returnf0dfnf:<EOL><INDENT>return f0, df, Nf, f0 + df * np.arange(Nf)<EOL><DEDENT>else:<EOL><INDENT>return f0 + df * np.arange(Nf)<EOL><DEDENT>

This calculates a frequency grid for the period finding functions in this
    module.

    Based on the autofrequency function in astropy.stats.lombscargle.

    http://docs.astropy.org/en/stable/_modules/astropy/stats/lombscargle/core.html#LombScargle.autofrequency

    Parameters
    ----------

    times : np.array
        The times to use to generate the frequency grid over.

    samplesperpeak : int
        The minimum sample coverage each frequency point in the grid will get.

    nyquistfactor : int
        The multiplier over the Nyquist rate to use.

    minfreq,maxfreq : float or None
        If not None, these will be the limits of the frequency grid generated.

    returnf0dfnf : bool
        If this is True, will return the values of `f0`, `df`, and `Nf`
        generated for this grid.

    Returns
    -------

    np.array
        A grid of frequencies.


def independent_freq_count(frequencies, times, conservative=True):

M = frequencies.ptp()*times.ptp()<EOL>if conservative:<EOL><INDENT>M_eff = min([times.size, frequencies.size, M])<EOL><DEDENT>else:<EOL><INDENT>M_eff = M<EOL><DEDENT>return M_eff<EOL>

This estimates M: the number of independent frequencies in the periodogram.

    This follows the terminology on page 3 of Zechmeister & Kurster (2009)::

        M = DELTA_f / delta_f

    where::

        DELTA_f = freq.max() - freq.min()
        delta_f = 1.0/(times.max() - times.min())

    Parameters
    ----------

    frequencies : np.array
        The frequencies array used for the calculation of the GLS periodogram.

    times : np.array
        The array of input times used for the calculation of the GLS
        periodogram.

    conservative : bool
        If True, will follow the prescription given in Schwarzenberg-Czerny
        (2003):

        http://adsabs.harvard.edu/abs/2003ASPC..292..383S

        and estimate the number of independent frequences as::

            min(N_obs, N_freq, DELTA_f/delta_f)

    Returns
    -------

    M : int
        The number of independent frequencies.


def make_combined_periodogram(pflist, outfile, addmethods=False):

import matplotlib.pyplot as plt<EOL>for pf in pflist:<EOL><INDENT>if pf['<STR_LIT>'] == '<STR_LIT>':<EOL><INDENT>plt.plot(pf['<STR_LIT>'],<EOL>np.max(pf['<STR_LIT>'])/pf['<STR_LIT>'] - <NUM_LIT:1.0>,<EOL>label='<STR_LIT>' % (pf['<STR_LIT>'], pf['<STR_LIT>']),<EOL>alpha=<NUM_LIT:0.5>)<EOL><DEDENT>else:<EOL><INDENT>plt.plot(pf['<STR_LIT>'],<EOL>pf['<STR_LIT>']/np.max(pf['<STR_LIT>']),<EOL>label='<STR_LIT>' % (pf['<STR_LIT>'], pf['<STR_LIT>']),<EOL>alpha=<NUM_LIT:0.5>)<EOL><DEDENT><DEDENT>plt.xlabel('<STR_LIT>')<EOL>plt.ylabel('<STR_LIT>')<EOL>plt.xscale('<STR_LIT>')<EOL>plt.legend()<EOL>plt.tight_layout()<EOL>plt.savefig(outfile)<EOL>plt.close('<STR_LIT:all>')<EOL>return outfile<EOL>

This just puts all of the period-finders on a single periodogram.

    This will renormalize all of the periodograms so their values lie between 0
    and 1, with values lying closer to 1 being more significant. Periodograms
    that give the same best periods will have their peaks line up together.

    Parameters
    ----------

    pflist : list of dict
        This is a list of result dicts from any of the period-finders in
        periodbase. To use your own period-finders' results here, make sure the
        result dict is of the form and has at least the keys below::

            {'periods': np.array of all periods searched by the period-finder,
             'lspvals': np.array of periodogram power value for each period,
             'bestperiod': a float value that is the period with the highest
                           peak in the periodogram, i.e. the most-likely actual
                           period,
             'method': a three-letter code naming the period-finder used; must
                       be one of the keys in the
                       `astrobase.periodbase.METHODLABELS` dict,
             'nbestperiods': a list of the periods corresponding to periodogram
                             peaks (`nbestlspvals` below) to annotate on the
                             periodogram plot so they can be called out
                             visually,
             'nbestlspvals': a list of the power values associated with
                             periodogram peaks to annotate on the periodogram
                             plot so they can be called out visually; should be
                             the same length as `nbestperiods` above,
             'kwargs': dict of kwargs passed to your own period-finder function}

    outfile : str
        This is the output file to write the output to. NOTE: EPS/PS won't work
        because we use alpha transparency to better distinguish between the
        various periodograms.

    addmethods : bool
        If this is True, will add all of the normalized periodograms together,
        then renormalize them to between 0 and 1. In this way, if all of the
        period-finders agree on something, it'll stand out easily. FIXME:
        implement this kwarg.

    Returns
    -------

    str
        The name of the generated plot file.


from scipy.stats import beta<EOL>frequencies = <NUM_LIT:1.0>/lspinfo['<STR_LIT>']<EOL>M = independent_freq_count(frequencies,<EOL>times,<EOL>conservative=conservative_nfreq_eff)<EOL>if peakvals is None:<EOL><INDENT>peakvals = lspinfo['<STR_LIT>']<EOL><DEDENT>nphasebins = nparange(<NUM_LIT:0.0>, <NUM_LIT:1.0>, lspinfo['<STR_LIT>']['<STR_LIT>']).size<EOL>ndet = times.size<EOL>false_alarm_probs = []<EOL>for peakval in peakvals:<EOL><INDENT>prob_xval = ((ndet-nphasebins)/(nphasebins-<NUM_LIT:1.0>))*peakval<EOL>prob_exceeds_val = beta.cdf(prob_xval,<EOL>(ndet-nphasebins)/<NUM_LIT>,<EOL>(nphasebins-<NUM_LIT:1.0>)/<NUM_LIT>)<EOL>import ipdb; ipdb.set_trace()<EOL>false_alarm_probs.append(<NUM_LIT:1.0> - (<NUM_LIT:1.0> - prob_exceeds_val)**M)<EOL><DEDENT>if inplace:<EOL><INDENT>lspinfo['<STR_LIT>'] = false_alarm_probs<EOL><DEDENT>return false_alarm_probs<EOL>

This returns the analytic false alarm probabilities for periodogram
    peak values.

    FIXME: this doesn't actually work. Fix later.

    The calculation follows that on page 3 of Zechmeister & Kurster (2009)::

        FAP = 1 − [1 − Prob(z > z0)]**M

    where::

        M is the number of independent frequencies
        Prob(z > z0) is the probability of peak with value > z0
        z0 is the peak value we're evaluating

    For PDM, the Prob(z > z0) is described by the beta distribution, according
    to:

    - Schwarzenberg-Czerny (1997;
      https://ui.adsabs.harvard.edu/#abs/1997ApJ...489..941S)

    - Zalian, Chadid, and Stellingwerf (2013;
      http://adsabs.harvard.edu/abs/2014MNRAS.440...68Z)

    This is given by::

        beta( (N-B)/2, (B-1)/2; ((N-B)/(B-1))*theta_pdm )

    Where::

        N = number of observations
        B = number of phase bins

    This translates to a scipy.stats call to the beta distribution CDF::

        x = ((N-B)/(B-1))*theta_pdm_best
        prob_exceeds_val = scipy.stats.beta.cdf(x, (N-B)/2.0, (B-1.0)/2.0)

    Which we can then plug into the false alarm prob eqn above with the
    calculation of M.

    Parameters
    ----------

    lspinfo : dict
        The dict returned by the
        :py:func:`~astrobase.periodbase.spdm.stellingwerf_pdm` function.

    times : np.array
        The times for which the periodogram result in ``lspinfo`` was
        calculated.

    conservative_nfreq_eff : bool
        If True, will follow the prescription given in Schwarzenberg-Czerny
        (2003):

        http://adsabs.harvard.edu/abs/2003ASPC..292..383S

        and estimate the effective number of independent frequences M_eff as::

            min(N_obs, N_freq, DELTA_f/delta_f)

    peakvals : sequence or None
        The peak values for which to evaluate the false-alarm probability. If
        None, will calculate this for each of the peak values in the
        ``nbestpeaks`` key of the ``lspinfo`` dict.

    inplace : bool
        If True, puts the results of the FAP calculation into the ``lspinfo``
        dict as a list available as ``lspinfo['falsealarmprob']``.

    Returns
    -------

    list
        The calculated false alarm probabilities for each of the peak values in
        ``peakvals``.


<EOL>stimes, smags, serrs = sigclip_magseries(times,<EOL>mags,<EOL>errs,<EOL>magsarefluxes=magsarefluxes,<EOL>sigclip=sigclip)<EOL>if len(stimes) > <NUM_LIT:9> and len(smags) > <NUM_LIT:9> and len(serrs) > <NUM_LIT:9>:<EOL><INDENT>if startp:<EOL><INDENT>endf = <NUM_LIT:1.0>/startp<EOL><DEDENT>else:<EOL><INDENT>endf = <NUM_LIT:1.0>/<NUM_LIT:0.1><EOL><DEDENT>if endp:<EOL><INDENT>startf = <NUM_LIT:1.0>/endp<EOL><DEDENT>else:<EOL><INDENT>startf = <NUM_LIT:1.0>/(stimes.max() - stimes.min())<EOL><DEDENT>if not autofreq:<EOL><INDENT>frequencies = nparange(startf, endf, stepsize)<EOL>if verbose:<EOL><INDENT>LOGINFO(<EOL>'<STR_LIT>' %<EOL>(frequencies.size, <NUM_LIT:1.0>/endf, <NUM_LIT:1.0>/startf)<EOL>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>frequencies = get_frequency_grid(stimes,<EOL>minfreq=startf,<EOL>maxfreq=endf)<EOL>if verbose:<EOL><INDENT>LOGINFO(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(frequencies.size,<EOL><NUM_LIT:1.0>/frequencies.max(),<EOL><NUM_LIT:1.0>/frequencies.min())<EOL>)<EOL><DEDENT><DEDENT>if (not nworkers) or (nworkers > NCPUS):<EOL><INDENT>nworkers = NCPUS<EOL>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>' % nworkers)<EOL><DEDENT><DEDENT>pool = Pool(nworkers)<EOL>if normalize:<EOL><INDENT>nmags = (smags - npmedian(smags))/npstd(smags)<EOL><DEDENT>else:<EOL><INDENT>nmags = smags<EOL><DEDENT>tasks = [(stimes, nmags, serrs, x, phasebinsize, mindetperbin)<EOL>for x in frequencies]<EOL>lsp = pool.map(_stellingwerf_pdm_worker, tasks)<EOL>pool.close()<EOL>pool.join()<EOL>del pool<EOL>lsp = nparray(lsp)<EOL>periods = <NUM_LIT:1.0>/frequencies<EOL>finitepeakind = npisfinite(lsp)<EOL>finlsp = lsp[finitepeakind]<EOL>finperiods = periods[finitepeakind]<EOL>try:<EOL><INDENT>bestperiodind = npargmin(finlsp)<EOL><DEDENT>except ValueError:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>return {'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':normalize,<EOL>'<STR_LIT>':phasebinsize,<EOL>'<STR_LIT>':mindetperbin,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip}}<EOL><DEDENT>sortedlspind = npargsort(finlsp)<EOL>sortedlspperiods = finperiods[sortedlspind]<EOL>sortedlspvals = finlsp[sortedlspind]<EOL>nbestperiods, nbestlspvals, peakcount = (<EOL>[finperiods[bestperiodind]],<EOL>[finlsp[bestperiodind]],<EOL><NUM_LIT:1><EOL>)<EOL>prevperiod = sortedlspperiods[<NUM_LIT:0>]<EOL>for period, lspval in zip(sortedlspperiods, sortedlspvals):<EOL><INDENT>if peakcount == nbestpeaks:<EOL><INDENT>break<EOL><DEDENT>perioddiff = abs(period - prevperiod)<EOL>bestperiodsdiff = [abs(period - x) for x in nbestperiods]<EOL>if (perioddiff > (periodepsilon*prevperiod) and<EOL>all(x > (periodepsilon*period) for x in bestperiodsdiff)):<EOL><INDENT>nbestperiods.append(period)<EOL>nbestlspvals.append(lspval)<EOL>peakcount = peakcount + <NUM_LIT:1><EOL><DEDENT>prevperiod = period<EOL><DEDENT>return {'<STR_LIT>':finperiods[bestperiodind],<EOL>'<STR_LIT>':finlsp[bestperiodind],<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':nbestlspvals,<EOL>'<STR_LIT>':nbestperiods,<EOL>'<STR_LIT>':lsp,<EOL>'<STR_LIT>':periods,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':normalize,<EOL>'<STR_LIT>':phasebinsize,<EOL>'<STR_LIT>':mindetperbin,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip}}<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>')<EOL>return {'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':normalize,<EOL>'<STR_LIT>':phasebinsize,<EOL>'<STR_LIT>':mindetperbin,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip}}<EOL><DEDENT>

This runs a parallelized Stellingwerf phase-dispersion minimization (PDM)
    period search.

    Parameters
    ----------

    times,mags,errs : np.array
        The mag/flux time-series with associated measurement errors to run the
        period-finding on.

    magsarefluxes : bool
        If the input measurement values in `mags` and `errs` are in fluxes, set
        this to True.

    startp,endp : float or None
        The minimum and maximum periods to consider for the transit search.

    stepsize : float
        The step-size in frequency to use when constructing a frequency grid for
        the period search.

    autofreq : bool
        If this is True, the value of `stepsize` will be ignored and the
        :py:func:`astrobase.periodbase.get_frequency_grid` function will be used
        to generate a frequency grid based on `startp`, and `endp`. If these are
        None as well, `startp` will be set to 0.1 and `endp` will be set to
        `times.max() - times.min()`.

    normalize : bool
        This sets if the input time-series is normalized to 0.0 and rescaled
        such that its variance = 1.0. This is the recommended procedure by
        Schwarzenberg-Czerny 1996.

    phasebinsize : float
        The bin size in phase to use when calculating the PDM theta statistic at
        a test frequency.

    mindetperbin : int
        The minimum number of elements in a phase bin to consider it valid when
        calculating the PDM theta statistic at a test frequency.

    nbestpeaks : int
        The number of 'best' peaks to return from the periodogram results,
        starting from the global maximum of the periodogram peak values.

    periodepsilon : float
        The fractional difference between successive values of 'best' periods
        when sorting by periodogram power to consider them as separate periods
        (as opposed to part of the same periodogram peak). This is used to avoid
        broad peaks in the periodogram and make sure the 'best' periods returned
        are all actually independent.

    sigclip : float or int or sequence of two floats/ints or None
        If a single float or int, a symmetric sigma-clip will be performed using
        the number provided as the sigma-multiplier to cut out from the input
        time-series.

        If a list of two ints/floats is provided, the function will perform an
        'asymmetric' sigma-clip. The first element in this list is the sigma
        value to use for fainter flux/mag values; the second element in this
        list is the sigma value to use for brighter flux/mag values. For
        example, `sigclip=[10., 3.]`, will sigclip out greater than 10-sigma
        dimmings and greater than 3-sigma brightenings. Here the meaning of
        "dimming" and "brightening" is set by *physics* (not the magnitude
        system), which is why the `magsarefluxes` kwarg must be correctly set.

        If `sigclip` is None, no sigma-clipping will be performed, and the
        time-series (with non-finite elems removed) will be passed through to
        the output.

    nworkers : int
        The number of parallel workers to use when calculating the periodogram.

    verbose : bool
        If this is True, will indicate progress and details about the frequency
        grid used for the period search.

    Returns
    -------

    dict
        This function returns a dict, referred to as an `lspinfo` dict in other
        astrobase functions that operate on periodogram results. This is a
        standardized format across all astrobase period-finders, and is of the
        form below::

            {'bestperiod': the best period value in the periodogram,
             'bestlspval': the periodogram peak associated with the best period,
             'nbestpeaks': the input value of nbestpeaks,
             'nbestlspvals': nbestpeaks-size list of best period peak values,
             'nbestperiods': nbestpeaks-size list of best periods,
             'lspvals': the full array of periodogram powers,
             'periods': the full array of periods considered,
             'method':'pdm' -> the name of the period-finder method,
             'kwargs':{ dict of all of the input kwargs for record-keeping}}


def macf_period_find(<EOL>times,<EOL>mags,<EOL>errs,<EOL>fillgaps=<NUM_LIT:0.0>,<EOL>filterwindow=<NUM_LIT:11>,<EOL>forcetimebin=None,<EOL>maxlags=None,<EOL>maxacfpeaks=<NUM_LIT:10>,<EOL>smoothacf=<NUM_LIT>,  <EOL>smoothfunc=_smooth_acf_savgol,<EOL>smoothfunckwargs=None,<EOL>magsarefluxes=False,<EOL>sigclip=<NUM_LIT>,<EOL>verbose=True,<EOL>periodepsilon=<NUM_LIT:0.1>,  <EOL>nworkers=None,      <EOL>startp=None,        <EOL>endp=None,          <EOL>autofreq=None,      <EOL>stepsize=None,      <EOL>):

<EOL>acfres = autocorr_magseries(<EOL>times,<EOL>mags,<EOL>errs,<EOL>maxlags=maxlags,<EOL>fillgaps=fillgaps,<EOL>forcetimebin=forcetimebin,<EOL>sigclip=sigclip,<EOL>magsarefluxes=magsarefluxes,<EOL>filterwindow=filterwindow,<EOL>verbose=verbose<EOL>)<EOL>xlags = acfres['<STR_LIT>']<EOL>if smoothacf and isinstance(smoothacf, int) and smoothacf > <NUM_LIT:0>:<EOL><INDENT>if smoothfunckwargs is None:<EOL><INDENT>sfkwargs = {'<STR_LIT>':smoothacf}<EOL><DEDENT>else:<EOL><INDENT>sfkwargs = smoothfunckwargs.copy()<EOL>sfkwargs.update({'<STR_LIT>':smoothacf})<EOL><DEDENT>xacf = smoothfunc(acfres['<STR_LIT>'], **sfkwargs)<EOL><DEDENT>else:<EOL><INDENT>xacf = acfres['<STR_LIT>']<EOL><DEDENT>peakres = _get_acf_peakheights(xlags, xacf, npeaks=maxacfpeaks,<EOL>searchinterval=int(smoothacf/<NUM_LIT:2>))<EOL>bestlspval = peakres['<STR_LIT>']<EOL>try:<EOL><INDENT>fity = npconcatenate((<EOL>[<NUM_LIT:0.0>, peakres['<STR_LIT>']],<EOL>peakres['<STR_LIT>'][peakres['<STR_LIT>'] > peakres['<STR_LIT>']]<EOL>))<EOL>fity = fity*acfres['<STR_LIT>']<EOL>fitx = nparange(fity.size)<EOL>fitcoeffs, fitcovar = nppolyfit(fitx, fity, <NUM_LIT:1>, cov=True)<EOL>fitbestperiod = fitcoeffs[<NUM_LIT:0>]<EOL>bestperiodrms = npsqrt(fitcovar[<NUM_LIT:0>,<NUM_LIT:0>])  <EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL>fitcoeffs = nparray([npnan, npnan])<EOL>fitcovar = nparray([[npnan, npnan], [npnan, npnan]])<EOL>fitbestperiod = npnan<EOL>bestperiodrms = npnan<EOL>raise<EOL><DEDENT>naivebestperiod = peakres['<STR_LIT>']*acfres['<STR_LIT>']<EOL>if fitbestperiod < naivebestperiod:<EOL><INDENT>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(fitbestperiod, naivebestperiod))<EOL><DEDENT>if npisfinite(fitbestperiod):<EOL><INDENT>bestperiod = fitbestperiod<EOL><DEDENT>else:<EOL><INDENT>bestperiod = naivebestperiod<EOL><DEDENT>return {'<STR_LIT>':bestperiod,<EOL>'<STR_LIT>':bestlspval,<EOL>'<STR_LIT>':maxacfpeaks,<EOL>'<STR_LIT>':npconcatenate([<EOL>[fitbestperiod],<EOL>peakres['<STR_LIT>'][<NUM_LIT:1>:maxacfpeaks]*acfres['<STR_LIT>']<EOL>]),<EOL>'<STR_LIT>':peakres['<STR_LIT>'][:maxacfpeaks],<EOL>'<STR_LIT>':xacf,<EOL>'<STR_LIT>':xlags*acfres['<STR_LIT>'],<EOL>'<STR_LIT>':xacf,<EOL>'<STR_LIT>':xlags,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':naivebestperiod,<EOL>'<STR_LIT>':fitbestperiod,<EOL>'<STR_LIT>':bestperiodrms,<EOL>'<STR_LIT>':fitcoeffs,<EOL>'<STR_LIT>':fitcovar,<EOL>'<STR_LIT>':{'<STR_LIT>':maxlags,<EOL>'<STR_LIT>':maxacfpeaks,<EOL>'<STR_LIT>':fillgaps,<EOL>'<STR_LIT>':filterwindow,<EOL>'<STR_LIT>':smoothacf,<EOL>'<STR_LIT>':sfkwargs,<EOL>'<STR_LIT>':magsarefluxes,<EOL>'<STR_LIT>':sigclip},<EOL>'<STR_LIT>':acfres,<EOL>'<STR_LIT>':peakres}<EOL>

This finds periods using the McQuillan+ (2013a, 2014) ACF method.

    The kwargs from `periodepsilon` to `stepsize` don't do anything but are used
    to present a consistent API for all periodbase period-finders to an outside
    driver (e.g. the one in the checkplotserver).

    Parameters
    ----------

    times,mags,errs : np.array
        The input magnitude/flux time-series to run the period-finding for.

    fillgaps : 'noiselevel' or float
        This sets what to use to fill in gaps in the time series. If this is
        'noiselevel', will smooth the light curve using a point window size of
        `filterwindow` (this should be an odd integer), subtract the smoothed LC
        from the actual LC and estimate the RMS. This RMS will be used to fill
        in the gaps. Other useful values here are 0.0, and npnan.

    filterwindow : int
        The light curve's smoothing filter window size to use if
        `fillgaps='noiselevel`'.

    forcetimebin : None or float
        This is used to force a particular cadence in the light curve other than
        the automatically determined cadence. This effectively rebins the light
        curve to this cadence. This should be in the same time units as `times`.

    maxlags : None or int
        This is the maximum number of lags to calculate. If None, will calculate
        all lags.

    maxacfpeaks : int
        This is the maximum number of ACF peaks to use when finding the highest
        peak and obtaining a fit period.

    smoothacf : int
        This is the number of points to use as the window size when smoothing
        the ACF with the `smoothfunc`. This should be an odd integer value. If
        this is None, will not smooth the ACF, but this will probably lead to
        finding spurious peaks in a generally noisy ACF.

        For Kepler, a value between 21 and 51 seems to work fine. For ground
        based data, much larger values may be necessary: between 1001 and 2001
        seem to work best for the HAT surveys. This is dependent on cadence, RMS
        of the light curve, the periods of the objects you're looking for, and
        finally, any correlated noise in the light curve. Make a plot of the
        smoothed/unsmoothed ACF vs. lag using the result dict of this function
        and the `plot_acf_results` function above to see the identified ACF
        peaks and what kind of smoothing might be needed.

        The value of `smoothacf` will also be used to figure out the interval to
        use when searching for local peaks in the ACF: this interval is 1/2 of
        the `smoothacf` value.

    smoothfunc : Python function
        This is the function that will be used to smooth the ACF. This should
        take at least one kwarg: 'windowsize'. Other kwargs can be passed in
        using a dict provided in `smoothfunckwargs`. By default, this uses a
        Savitsky-Golay filter, a Gaussian filter is also provided but not
        used. Another good option would be an actual low-pass filter (generated
        using scipy.signal?) to remove all high frequency noise from the ACF.

    smoothfunckwargs : dict or None
        The dict of optional kwargs to pass in to the `smoothfunc`.

    magsarefluxes : bool
        If your input measurements in `mags` are actually fluxes instead of
        mags, set this is True.

    sigclip : float or int or sequence of two floats/ints or None
        If a single float or int, a symmetric sigma-clip will be performed using
        the number provided as the sigma-multiplier to cut out from the input
        time-series.

        If a list of two ints/floats is provided, the function will perform an
        'asymmetric' sigma-clip. The first element in this list is the sigma
        value to use for fainter flux/mag values; the second element in this
        list is the sigma value to use for brighter flux/mag values. For
        example, `sigclip=[10., 3.]`, will sigclip out greater than 10-sigma
        dimmings and greater than 3-sigma brightenings. Here the meaning of
        "dimming" and "brightening" is set by *physics* (not the magnitude
        system), which is why the `magsarefluxes` kwarg must be correctly set.

        If `sigclip` is None, no sigma-clipping will be performed, and the
        time-series (with non-finite elems removed) will be passed through to
        the output.

    verbose : bool
        If True, will indicate progress and report errors.

    Returns
    -------

    dict
        Returns a dict with results. dict['bestperiod'] is the estimated best
        period and dict['fitperiodrms'] is its estimated error. Other
        interesting things in the output include:

        - dict['acfresults']: all results from calculating the ACF. in
          particular, the unsmoothed ACF might be of interest:
          dict['acfresults']['acf'] and dict['acfresults']['lags'].

        - dict['lags'] and dict['acf'] contain the ACF after smoothing was
          applied.

        - dict['periods'] and dict['lspvals'] can be used to construct a
          pseudo-periodogram.

        - dict['naivebestperiod'] is obtained by multiplying the lag at the
          highest ACF peak with the cadence. This is usually close to the fit
          period (dict['fitbestperiod']), which is calculated by doing a fit to
          the lags vs. peak index relation as in McQuillan+ 2014.


def _smooth_acf_savgol(acf, windowsize=<NUM_LIT>, polyorder=<NUM_LIT:2>):

smoothed = savgol_filter(acf, windowsize, polyorder)<EOL>return smoothed<EOL>

This returns a smoothed version of the ACF.

This version uses the Savitsky-Golay smoothing filter.

Parameters
----------

acf : np.array
    The auto-correlation function array to smooth.

windowsize : int
    The number of input points to apply the smoothing over.

polyorder : int
    The order of the polynomial to use in the Savitsky-Golay filter.

Returns
-------

np.array
    Smoothed version of the input ACF array.


def plot_acf_results(acfp, outfile, maxlags=<NUM_LIT>, yrange=(-<NUM_LIT>,<NUM_LIT>)):

import matplotlib.pyplot as plt<EOL>lags = acfp['<STR_LIT>']['<STR_LIT>'][:maxlags]<EOL>smoothedacf = acfp['<STR_LIT>'][:maxlags]<EOL>unsmoothedacf = acfp['<STR_LIT>']['<STR_LIT>'][:maxlags]<EOL>acfparams = acfp['<STR_LIT>']['<STR_LIT>'].copy()<EOL>acfparams.update({'<STR_LIT>': int(acfp['<STR_LIT>']['<STR_LIT>']/<NUM_LIT>)})<EOL>fig, ax1 = plt.subplots()<EOL>ax1.plot(lags, unsmoothedacf, label='<STR_LIT>',color='<STR_LIT>')<EOL>ax1.plot(lags, smoothedacf, label='<STR_LIT>', color='<STR_LIT>')<EOL>ax1.set_xlim((<NUM_LIT:0>,maxlags))<EOL>ax1.set_xlabel('<STR_LIT>')<EOL>acfmaxinds = acfp['<STR_LIT>']['<STR_LIT>']<EOL>for i, maxind in enumerate(acfmaxinds):<EOL><INDENT>if i == <NUM_LIT:0>:<EOL><INDENT>ax1.axvline(maxind,<EOL>linewidth=<NUM_LIT>,<EOL>color='<STR_LIT>',<EOL>ymin=<NUM_LIT>, ymax=<NUM_LIT>,<EOL>label='<STR_LIT>')<EOL><DEDENT>else:<EOL><INDENT>ax1.axvline(maxind,<EOL>linewidth=<NUM_LIT>,<EOL>color='<STR_LIT>',<EOL>ymin=<NUM_LIT>, ymax=<NUM_LIT>)<EOL><DEDENT><DEDENT>plt.ylabel('<STR_LIT>')<EOL>plt.ylim(yrange)<EOL>ax1.legend()<EOL>plt.title('<STR_LIT:%s>' % repr(acfparams))<EOL>plt.tight_layout()<EOL>plt.savefig(outfile)<EOL>plt.close('<STR_LIT:all>')<EOL>return outfile<EOL>

This plots the unsmoothed/smoothed ACF vs lag.

Parameters
----------

acfp : dict
    This is the dict returned from `macf_period_find` below.

outfile : str
    The output file the plot will be written to.

maxlags: int
    The maximum number of lags to include in the plot.

yrange : sequence of two floats
    The y-range of the ACF vs. lag plot to use.


def _smooth_acf(acf, windowfwhm=<NUM_LIT:7>, windowsize=<NUM_LIT>):

convkernel = Gaussian1DKernel(windowfwhm, x_size=windowsize)<EOL>smoothed = convolve(acf, convkernel, boundary='<STR_LIT>')<EOL>return smoothed<EOL>

This returns a smoothed version of the ACF.

    Convolves the ACF with a Gaussian of given `windowsize` and `windowfwhm`.

    Parameters
    ----------

    acf : np.array
        The auto-correlation function array to smooth.

    windowfwhm : int
        The smoothing window Gaussian kernel's FWHM .

    windowsize : int
        The number of input points to apply the smoothing over.

    Returns
    -------

    np.array
        Smoothed version of the input ACF array.


def parallel_townsend_lsp_sharedarray(times, mags, startp, endp,<EOL>stepsize=<NUM_LIT>,<EOL>nworkers=<NUM_LIT:16>):

This is a version of the above which uses shared ctypes arrays for the times
and mags arrays so as not to copy them to each worker process.

TODO: we'll need to pass a single argument to the worker so make a 2D array
and wrap the worker function with partial?

FIXME: implement this later.


try:<EOL><INDENT>return townsend_lombscargle_value(*task)<EOL><DEDENT>except Exception as e:<EOL><INDENT>return npnan<EOL><DEDENT>

This wraps the function above for use with mp.Pool.

task[0] = times
task[1] = mags
task[2] = omega


frequency = task[<NUM_LIT:0>]<EOL>times, modmags = task[<NUM_LIT:1>], task[<NUM_LIT:2>]<EOL>fold_time = task[<NUM_LIT:3>]<EOL>j_range = range(task[<NUM_LIT:4>])<EOL>keep_threshold_1 = task[<NUM_LIT:5>]<EOL>keep_threshold_2 = task[<NUM_LIT:6>]<EOL>phasebinsize = task[<NUM_LIT:7>]<EOL>try:<EOL><INDENT>period = <NUM_LIT:1.0>/frequency<EOL>phased = phase_magseries(times,<EOL>modmags,<EOL>period,<EOL>fold_time,<EOL>wrap=False,<EOL>sort=True)<EOL>if phasebinsize is not None and phasebinsize > <NUM_LIT:0>:<EOL><INDENT>bphased = pwd_phasebin(phased['<STR_LIT>'],<EOL>phased['<STR_LIT>'],<EOL>binsize=phasebinsize)<EOL>phase_sorted = bphased[<NUM_LIT:0>]<EOL>mod_mag_sorted = bphased[<NUM_LIT:1>]<EOL>j_range = range(len(mod_mag_sorted) - <NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>phase_sorted = phased['<STR_LIT>']<EOL>mod_mag_sorted = phased['<STR_LIT>']<EOL><DEDENT>rolledmags = nproll(mod_mag_sorted,<NUM_LIT:1>)<EOL>rolledphases = nproll(phase_sorted,<NUM_LIT:1>)<EOL>strings = (<EOL>(rolledmags - mod_mag_sorted)*(rolledmags - mod_mag_sorted) +<EOL>(rolledphases - phase_sorted)*(rolledphases - phase_sorted)<EOL>)<EOL>strings[<NUM_LIT:0>] = (<EOL>((mod_mag_sorted[<NUM_LIT:0>] - mod_mag_sorted[-<NUM_LIT:1>]) *<EOL>(mod_mag_sorted[<NUM_LIT:0>] - mod_mag_sorted[-<NUM_LIT:1>])) +<EOL>((phase_sorted[<NUM_LIT:0>] - phase_sorted[-<NUM_LIT:1>] + <NUM_LIT:1>) *<EOL>(phase_sorted[<NUM_LIT:0>] - phase_sorted[-<NUM_LIT:1>] + <NUM_LIT:1>))<EOL>)<EOL>strlen = npsum(npsqrt(strings))<EOL>if (keep_threshold_1 < strlen < keep_threshold_2):<EOL><INDENT>p_goodflag  = True<EOL><DEDENT>else:<EOL><INDENT>p_goodflag = False<EOL><DEDENT>return (period, strlen, p_goodflag)<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>')<EOL>return(period, npnan, False)<EOL><DEDENT>

This is the parallel worker for the function below.

task[0] = frequency for this worker
task[1] = times array
task[2] = mags array
task[3] = fold_time
task[4] = j_range
task[5] = keep_threshold_1
task[6] = keep_threshold_2
task[7] = phasebinsize

we don't need errs for the worker.


<EOL>find = npisfinite(times) & npisfinite(mags) & npisfinite(errs)<EOL>ftimes, fmags, ferrs = times[find], mags[find], errs[find]<EOL>mod_mags = (fmags - npmin(fmags))/(<NUM_LIT>*(npmax(fmags) - npmin(fmags))) - <NUM_LIT><EOL>if len(ftimes) > <NUM_LIT:9> and len(fmags) > <NUM_LIT:9> and len(ferrs) > <NUM_LIT:9>:<EOL><INDENT>median_mag = np.median(fmags)<EOL>stddev_mag = (np.median(np.abs(fmags - median_mag))) * <NUM_LIT><EOL>if sigclip:<EOL><INDENT>sigind = (np.abs(fmags - median_mag)) < (sigclip * stddev_mag)<EOL>stimes = ftimes[sigind]<EOL>smags = fmags[sigind]<EOL>serrs = ferrs[sigind]<EOL>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(sigclip, len(times), len(stimes)))<EOL><DEDENT>else:<EOL><INDENT>stimes = ftimes<EOL>smags = fmags<EOL>serrs = ferrs<EOL><DEDENT>if len(stimes) > <NUM_LIT:9> and len(smags) > <NUM_LIT:9> and len(serrs) > <NUM_LIT:9>:<EOL><INDENT>if init_p:<EOL><INDENT>endf = <NUM_LIT:1.0>/init_p<EOL><DEDENT>else:<EOL><INDENT>endf = <NUM_LIT:1.0>/<NUM_LIT:0.1><EOL><DEDENT>if end_p:<EOL><INDENT>startf = <NUM_LIT:1.0>/end_p<EOL><DEDENT>else:<EOL><INDENT>startf = <NUM_LIT:1.0>/(stimes.max() - stimes.min())<EOL><DEDENT>if not autofreq:<EOL><INDENT>frequencies = np.arange(startf, endf, stepsize)<EOL>LOGINFO(<EOL>'<STR_LIT>' %<EOL>(frequencies.size, <NUM_LIT:1.0>/endf, <NUM_LIT:1.0>/startf)<EOL>)<EOL><DEDENT>else:<EOL><INDENT>frequencies = get_frequency_grid(stimes,<EOL>minfreq=startf,<EOL>maxfreq=endf)<EOL>LOGINFO(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(frequencies.size,<EOL><NUM_LIT:1.0>/frequencies.max(),<EOL><NUM_LIT:1.0>/frequencies.min())<EOL>)<EOL><DEDENT>fold_time = npmin(ftimes) <EOL>j_range = len(fmags)-<NUM_LIT:1><EOL>epsilon = <NUM_LIT> * npmean(ferrs)<EOL>delta_l = <NUM_LIT> * (epsilon - <NUM_LIT:0.5>*(epsilon**<NUM_LIT:2>)) * (len(ftimes) -<EOL>npsqrt(<NUM_LIT>/epsilon))<EOL>keep_threshold_1 = <NUM_LIT> + <NUM_LIT>*delta_l<EOL>l = <NUM_LIT>*len(ftimes)<EOL>sig_l = len(ftimes)/<NUM_LIT><EOL>keep_threshold_2 = l + <NUM_LIT>*sig_l<EOL>tasks = [(x,<EOL>ftimes,<EOL>mod_mags,<EOL>fold_time,<EOL>j_range,<EOL>keep_threshold_1,<EOL>keep_threshold_2,<EOL>phasebinsize) for x in frequencies]<EOL>if (not nworkers) or (nworkers > NCPUS):<EOL><INDENT>nworkers = NCPUS<EOL>LOGINFO('<STR_LIT>' % nworkers)<EOL><DEDENT>pool = Pool(nworkers)<EOL>strlen_results = pool.map(pdw_worker, tasks)<EOL>pool.close()<EOL>pool.join()<EOL>del pool<EOL>periods, strlens, goodflags = zip(*strlen_results)<EOL>periods, strlens, goodflags = (np.array(periods),<EOL>np.array(strlens),<EOL>np.array(goodflags))<EOL>strlensort = npargsort(strlens)<EOL>nbeststrlens = strlens[strlensort[:<NUM_LIT:5>]]<EOL>nbestperiods = periods[strlensort[:<NUM_LIT:5>]]<EOL>nbestflags = goodflags[strlensort[:<NUM_LIT:5>]]<EOL>bestperiod = nbestperiods[<NUM_LIT:0>]<EOL>beststrlen = nbeststrlens[<NUM_LIT:0>]<EOL>bestflag = nbestflags[<NUM_LIT:0>]<EOL>return {'<STR_LIT>':bestperiod,<EOL>'<STR_LIT>':beststrlen,<EOL>'<STR_LIT>':bestflag,<EOL>'<STR_LIT>':nbeststrlens,<EOL>'<STR_LIT>':nbestperiods,<EOL>'<STR_LIT>':nbestflags,<EOL>'<STR_LIT>':strlens,<EOL>'<STR_LIT>':periods,<EOL>'<STR_LIT>':goodflags}<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>')<EOL>return {'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None}<EOL><DEDENT><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>')<EOL>return {'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None}<EOL><DEDENT>

This is the parallel version of the function above.

    Uses the string length method in Dworetsky 1983 to calculate the period of a
    time-series of magnitude measurements and associated magnitude errors. This
    can optionally bin in phase to try to speed up the calculation.

    PARAMETERS:

    time: series of times at which mags were measured (usually some form of JD)
    mag: timeseries of magnitudes (np.array)
    err: associated errs per magnitude measurement (np.array)
    init_p, end_p: interval to search for periods between (both ends inclusive)
    f_step: step in frequency [days^-1] to use

    RETURNS:

    tuple of the following form:

    (periods (np.array),
     string_lengths (np.array),
     good_period_mask (boolean array))


baseline = times.max() - times.min()<EOL>nsamples = times.size<EOL>df = <NUM_LIT:1.> / baseline / samplesperpeak<EOL>if minfreq is not None:<EOL><INDENT>f0 = minfreq<EOL><DEDENT>else:<EOL><INDENT>f0 = <NUM_LIT:0.5> * df<EOL><DEDENT>if maxfreq is not None:<EOL><INDENT>Nf = int(npceil((maxfreq - f0) / df))<EOL><DEDENT>else:<EOL><INDENT>Nf = int(<NUM_LIT:0.5> * samplesperpeak * nyquistfactor * nsamples)<EOL><DEDENT>if returnf0dfnf:<EOL><INDENT>return f0, df, Nf, f0 + df * nparange(Nf)<EOL><DEDENT>else:<EOL><INDENT>return f0 + df * nparange(Nf)<EOL><DEDENT>

This calculates a frequency grid for the period finding functions in this
    module.

    Based on the autofrequency function in astropy.stats.lombscargle.

    http://docs.astropy.org/en/stable/_modules/astropy/stats/lombscargle/core.html#LombScargle.autofrequency


def pwd_phasebin(phases, mags, binsize=<NUM_LIT>, minbin=<NUM_LIT:9>):

bins = np.arange(<NUM_LIT:0.0>, <NUM_LIT:1.0>, binsize)<EOL>binnedphaseinds = npdigitize(phases, bins)<EOL>binnedphases, binnedmags = [], []<EOL>for x in npunique(binnedphaseinds):<EOL><INDENT>thisbin_inds = binnedphaseinds == x<EOL>thisbin_phases = phases[thisbin_inds]<EOL>thisbin_mags = mags[thisbin_inds]<EOL>if thisbin_inds.size > minbin:<EOL><INDENT>binnedphases.append(npmedian(thisbin_phases))<EOL>binnedmags.append(npmedian(thisbin_mags))<EOL><DEDENT><DEDENT>return np.array(binnedphases), np.array(binnedmags)<EOL>

This bins the phased mag series using the given binsize.


def townsend_lombscargle_value(times, mags, omega):

cos_omegat = npcos(omega*times)<EOL>sin_omegat = npsin(omega*times)<EOL>xc = npsum(mags*cos_omegat)<EOL>xs = npsum(mags*sin_omegat)<EOL>cc = npsum(cos_omegat*cos_omegat)<EOL>ss = npsum(sin_omegat*sin_omegat)<EOL>cs = npsum(cos_omegat*sin_omegat)<EOL>tau = nparctan(<NUM_LIT:2>*cs/(cc - ss))/(<NUM_LIT:2>*omega)<EOL>ctau = npcos(omega*tau)<EOL>stau = npsin(omega*tau)<EOL>leftsumtop = (ctau*xc + stau*xs)*(ctau*xc + stau*xs)<EOL>leftsumbot = ctau*ctau*cc + <NUM_LIT>*ctau*stau*cs + stau*stau*ss<EOL>leftsum = leftsumtop/leftsumbot<EOL>rightsumtop = (ctau*xs - stau*xc)*(ctau*xs - stau*xc)<EOL>rightsumbot = ctau*ctau*ss - <NUM_LIT>*ctau*stau*cs + stau*stau*cc<EOL>rightsum = rightsumtop/rightsumbot<EOL>pval = <NUM_LIT:0.5>*(leftsum + rightsum)<EOL>return pval<EOL>

This calculates the periodogram value for each omega (= 2*pi*f). Mags must
be normalized to zero with variance scaled to unity.


<EOL>stimes, smags, serrs = sigclip_magseries(times,<EOL>mags,<EOL>errs,<EOL>magsarefluxes=magsarefluxes,<EOL>sigclip=sigclip)<EOL>if len(stimes) > <NUM_LIT:9> and len(smags) > <NUM_LIT:9> and len(serrs) > <NUM_LIT:9>:<EOL><INDENT>if startp:<EOL><INDENT>endf = <NUM_LIT:1.0>/startp<EOL><DEDENT>else:<EOL><INDENT>endf = <NUM_LIT:1.0>/<NUM_LIT:0.1><EOL><DEDENT>if endp:<EOL><INDENT>startf = <NUM_LIT:1.0>/endp<EOL><DEDENT>else:<EOL><INDENT>startf = <NUM_LIT:1.0>/(stimes.max() - stimes.min())<EOL><DEDENT>if not autofreq:<EOL><INDENT>frequencies = nparange(startf, endf, stepsize)<EOL>if verbose:<EOL><INDENT>LOGINFO(<EOL>'<STR_LIT>' %<EOL>(frequencies.size, <NUM_LIT:1.0>/endf, <NUM_LIT:1.0>/startf)<EOL>)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>frequencies = get_frequency_grid(stimes,<EOL>minfreq=startf,<EOL>maxfreq=endf)<EOL>if verbose:<EOL><INDENT>LOGINFO(<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(frequencies.size,<EOL><NUM_LIT:1.0>/frequencies.max(),<EOL><NUM_LIT:1.0>/frequencies.min())<EOL>)<EOL><DEDENT><DEDENT>if (not nworkers) or (nworkers > NCPUS):<EOL><INDENT>nworkers = NCPUS<EOL>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>' % nworkers)<EOL><DEDENT><DEDENT>pool = Pool(nworkers)<EOL>if normalize:<EOL><INDENT>nmags = (smags - npmedian(smags))/npstd(smags)<EOL><DEDENT>else:<EOL><INDENT>nmags = smags<EOL><DEDENT>magvariance_top = npsum(nmags/(serrs*serrs))<EOL>magvariance_bot = (nmags.size - <NUM_LIT:1>)*npsum(<NUM_LIT:1.0>/(serrs*serrs)) / nmags.size<EOL>magvariance = magvariance_top/magvariance_bot<EOL>tasks = [(stimes, nmags, serrs, x, nharmonics, magvariance)<EOL>for x in frequencies]<EOL>lsp = pool.map(_aovhm_theta_worker, tasks)<EOL>pool.close()<EOL>pool.join()<EOL>del pool<EOL>lsp = nparray(lsp)<EOL>periods = <NUM_LIT:1.0>/frequencies<EOL>finitepeakind = npisfinite(lsp)<EOL>finlsp = lsp[finitepeakind]<EOL>finperiods = periods[finitepeakind]<EOL>try:<EOL><INDENT>bestperiodind = npargmax(finlsp)<EOL><DEDENT>except ValueError:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>return {'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':normalize,<EOL>'<STR_LIT>':nharmonics,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip}}<EOL><DEDENT>sortedlspind = npargsort(finlsp)[::-<NUM_LIT:1>]<EOL>sortedlspperiods = finperiods[sortedlspind]<EOL>sortedlspvals = finlsp[sortedlspind]<EOL>nbestperiods, nbestlspvals, peakcount = (<EOL>[finperiods[bestperiodind]],<EOL>[finlsp[bestperiodind]],<EOL><NUM_LIT:1><EOL>)<EOL>prevperiod = sortedlspperiods[<NUM_LIT:0>]<EOL>for period, lspval in zip(sortedlspperiods, sortedlspvals):<EOL><INDENT>if peakcount == nbestpeaks:<EOL><INDENT>break<EOL><DEDENT>perioddiff = abs(period - prevperiod)<EOL>bestperiodsdiff = [abs(period - x) for x in nbestperiods]<EOL>if (perioddiff > (periodepsilon*prevperiod) and<EOL>all(x > (periodepsilon*period) for x in bestperiodsdiff)):<EOL><INDENT>nbestperiods.append(period)<EOL>nbestlspvals.append(lspval)<EOL>peakcount = peakcount + <NUM_LIT:1><EOL><DEDENT>prevperiod = period<EOL><DEDENT>return {'<STR_LIT>':finperiods[bestperiodind],<EOL>'<STR_LIT>':finlsp[bestperiodind],<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':nbestlspvals,<EOL>'<STR_LIT>':nbestperiods,<EOL>'<STR_LIT>':lsp,<EOL>'<STR_LIT>':periods,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':normalize,<EOL>'<STR_LIT>':nharmonics,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip}}<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>')<EOL>return {'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':normalize,<EOL>'<STR_LIT>':nharmonics,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip}}<EOL><DEDENT>

This runs a parallelized harmonic Analysis-of-Variance (AoV) period
    search.

    NOTE: normalize = True here as recommended by Schwarzenberg-Czerny 1996,
    i.e. mags will be normalized to zero and rescaled so their variance = 1.0.

    Parameters
    ----------

    times,mags,errs : np.array
        The mag/flux time-series with associated measurement errors to run the
        period-finding on.

    magsarefluxes : bool
        If the input measurement values in `mags` and `errs` are in fluxes, set
        this to True.

    startp,endp : float or None
        The minimum and maximum periods to consider for the transit search.

    stepsize : float
        The step-size in frequency to use when constructing a frequency grid for
        the period search.

    autofreq : bool
        If this is True, the value of `stepsize` will be ignored and the
        :py:func:`astrobase.periodbase.get_frequency_grid` function will be used
        to generate a frequency grid based on `startp`, and `endp`. If these are
        None as well, `startp` will be set to 0.1 and `endp` will be set to
        `times.max() - times.min()`.

    normalize : bool
        This sets if the input time-series is normalized to 0.0 and rescaled
        such that its variance = 1.0. This is the recommended procedure by
        Schwarzenberg-Czerny 1996.

    nharmonics : int
        The number of harmonics to use when calculating the AoV theta value at a
        test frequency. This should be between 4 and 8 in most cases.

    nbestpeaks : int
        The number of 'best' peaks to return from the periodogram results,
        starting from the global maximum of the periodogram peak values.

    periodepsilon : float
        The fractional difference between successive values of 'best' periods
        when sorting by periodogram power to consider them as separate periods
        (as opposed to part of the same periodogram peak). This is used to avoid
        broad peaks in the periodogram and make sure the 'best' periods returned
        are all actually independent.

    sigclip : float or int or sequence of two floats/ints or None
        If a single float or int, a symmetric sigma-clip will be performed using
        the number provided as the sigma-multiplier to cut out from the input
        time-series.

        If a list of two ints/floats is provided, the function will perform an
        'asymmetric' sigma-clip. The first element in this list is the sigma
        value to use for fainter flux/mag values; the second element in this
        list is the sigma value to use for brighter flux/mag values. For
        example, `sigclip=[10., 3.]`, will sigclip out greater than 10-sigma
        dimmings and greater than 3-sigma brightenings. Here the meaning of
        "dimming" and "brightening" is set by *physics* (not the magnitude
        system), which is why the `magsarefluxes` kwarg must be correctly set.

        If `sigclip` is None, no sigma-clipping will be performed, and the
        time-series (with non-finite elems removed) will be passed through to
        the output.

    nworkers : int
        The number of parallel workers to use when calculating the periodogram.

    verbose : bool
        If this is True, will indicate progress and details about the frequency
        grid used for the period search.

    Returns
    -------

    dict
        This function returns a dict, referred to as an `lspinfo` dict in other
        astrobase functions that operate on periodogram results. This is a
        standardized format across all astrobase period-finders, and is of the
        form below::

            {'bestperiod': the best period value in the periodogram,
             'bestlspval': the periodogram peak associated with the best period,
             'nbestpeaks': the input value of nbestpeaks,
             'nbestlspvals': nbestpeaks-size list of best period peak values,
             'nbestperiods': nbestpeaks-size list of best periods,
             'lspvals': the full array of periodogram powers,
             'periods': the full array of periods considered,
             'method':'mav' -> the name of the period-finder method,
             'kwargs':{ dict of all of the input kwargs for record-keeping}}


try:<EOL><INDENT>times, mags, errs = task[:<NUM_LIT:3>]<EOL>magsarefluxes = task[<NUM_LIT:3>]<EOL>minfreq, nfreq, stepsize = task[<NUM_LIT:4>:<NUM_LIT:7>]<EOL>ndurations, mintransitduration, maxtransitduration = task[<NUM_LIT:7>:<NUM_LIT:10>]<EOL>blsobjective, blsmethod, blsoversample = task[<NUM_LIT:10>:]<EOL>frequencies = minfreq + nparange(nfreq)*stepsize<EOL>periods = <NUM_LIT:1.0>/frequencies<EOL>durations = nplinspace(mintransitduration*periods.min(),<EOL>maxtransitduration*periods.min(),<EOL>ndurations)<EOL>if magsarefluxes:<EOL><INDENT>blsmodel = BoxLeastSquares(<EOL>times*u.day,<EOL>mags*u.dimensionless_unscaled,<EOL>dy=errs*u.dimensionless_unscaled<EOL>)<EOL><DEDENT>else:<EOL><INDENT>blsmodel = BoxLeastSquares(<EOL>times*u.day,<EOL>mags*u.mag,<EOL>dy=errs*u.mag<EOL>)<EOL><DEDENT>blsresult = blsmodel.power(<EOL>periods*u.day,<EOL>durations*u.day,<EOL>objective=blsobjective,<EOL>method=blsmethod,<EOL>oversample=blsoversample<EOL>)<EOL>return {<EOL>'<STR_LIT>': blsresult,<EOL>'<STR_LIT>': blsmodel,<EOL>'<STR_LIT>': durations,<EOL>'<STR_LIT>': nparray(blsresult.power)<EOL>}<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>' %<EOL>(frequencies[<NUM_LIT:0>], frequencies[-<NUM_LIT:1>]))<EOL>return {<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': None,<EOL>'<STR_LIT>': durations,<EOL>'<STR_LIT>': nparray([npnan for x in range(nfreq)]),<EOL>}<EOL><DEDENT>

This wraps Astropy's BoxLeastSquares for use with bls_parallel_pfind below.

`task` is a tuple::

    task[0] = times
    task[1] = mags
    task[2] = errs
    task[3] = magsarefluxes

    task[4] = minfreq
    task[5] = nfreq
    task[6] = stepsize

    task[7] = ndurations
    task[8] = mintransitduration
    task[9] = maxtransitduration

    task[10] = blsobjective
    task[11] = blsmethod
    task[12] = blsoversample


def bls_serial_pfind(times, mags, errs,<EOL>magsarefluxes=False,<EOL>startp=<NUM_LIT:0.1>,  <EOL>endp=<NUM_LIT>,  <EOL>stepsize=<NUM_LIT>,<EOL>mintransitduration=<NUM_LIT>,  <EOL>maxtransitduration=<NUM_LIT>,   <EOL>ndurations=<NUM_LIT:100>,<EOL>autofreq=True,  <EOL>blsobjective='<STR_LIT>',<EOL>blsmethod='<STR_LIT>',<EOL>blsoversample=<NUM_LIT:10>,<EOL>blsmintransits=<NUM_LIT:3>,<EOL>blsfreqfactor=<NUM_LIT>,<EOL>periodepsilon=<NUM_LIT:0.1>,<EOL>nbestpeaks=<NUM_LIT:5>,<EOL>sigclip=<NUM_LIT>,<EOL>verbose=True,<EOL>raiseonfail=False):

<EOL>stimes, smags, serrs = sigclip_magseries(times,<EOL>mags,<EOL>errs,<EOL>magsarefluxes=magsarefluxes,<EOL>sigclip=sigclip)<EOL>if len(stimes) > <NUM_LIT:9> and len(smags) > <NUM_LIT:9> and len(serrs) > <NUM_LIT:9>:<EOL><INDENT>if isinstance(autofreq, bool) and autofreq:<EOL><INDENT>stepsize = <NUM_LIT>*mintransitduration/(stimes.max()-stimes.min())<EOL>minfreq = <NUM_LIT:1.0>/endp<EOL>maxfreq = <NUM_LIT:1.0>/startp<EOL>nfreq = int(npceil((maxfreq - minfreq)/stepsize))<EOL>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>' % (startp, endp, nfreq,<EOL>minfreq, maxfreq))<EOL>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(stepsize, ndurations,<EOL>mintransitduration, maxtransitduration))<EOL><DEDENT>use_autoperiod = False<EOL><DEDENT>elif isinstance(autofreq, bool) and not autofreq:<EOL><INDENT>minfreq = <NUM_LIT:1.0>/endp<EOL>maxfreq = <NUM_LIT:1.0>/startp<EOL>nfreq = int(npceil((maxfreq - minfreq)/stepsize))<EOL>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>' % (startp, endp, nfreq,<EOL>minfreq, maxfreq))<EOL>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(stepsize, ndurations,<EOL>mintransitduration, maxtransitduration))<EOL><DEDENT>use_autoperiod = False<EOL><DEDENT>elif isinstance(autofreq, str) and autofreq == '<STR_LIT>':<EOL><INDENT>use_autoperiod = True<EOL>minfreq = <NUM_LIT:1.0>/endp<EOL>maxfreq = <NUM_LIT:1.0>/startp<EOL><DEDENT>else:<EOL><INDENT>LOGERROR("<STR_LIT>")<EOL>return None<EOL><DEDENT>if minfreq < (<NUM_LIT:1.0>/(stimes.max() - stimes.min())):<EOL><INDENT>if verbose:<EOL><INDENT>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>% (endp, stimes.max() - stimes.min()))<EOL><DEDENT>minfreq = <NUM_LIT>/(stimes.max() - stimes.min())<EOL>if verbose:<EOL><INDENT>LOGINFO('<STR_LIT>' %<EOL>(minfreq, maxfreq))<EOL><DEDENT><DEDENT>try:<EOL><INDENT>durations = nplinspace(mintransitduration*startp,<EOL>maxtransitduration*startp,<EOL>ndurations)<EOL>if magsarefluxes:<EOL><INDENT>blsmodel = BoxLeastSquares(<EOL>stimes*u.day,<EOL>smags*u.dimensionless_unscaled,<EOL>dy=serrs*u.dimensionless_unscaled<EOL>)<EOL><DEDENT>else:<EOL><INDENT>blsmodel = BoxLeastSquares(<EOL>stimes*u.day,<EOL>smags*u.mag,<EOL>dy=serrs*u.mag<EOL>)<EOL><DEDENT>if use_autoperiod:<EOL><INDENT>periods = nparray(<EOL>blsmodel.autoperiod(<EOL>durations,<EOL>minimum_period=startp,<EOL>maximum_period=endp,<EOL>minimum_n_transit=blsmintransits,<EOL>frequency_factor=blsfreqfactor<EOL>)<EOL>)<EOL>nfreq = periods.size<EOL>if verbose:<EOL><INDENT>LOGINFO(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(blsmintransits, blsfreqfactor)<EOL>)<EOL>LOGINFO('<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>(abs(<NUM_LIT:1.0>/periods[<NUM_LIT:1>] - <NUM_LIT:1.0>/periods[<NUM_LIT:0>]),<EOL>nfreq,<EOL><NUM_LIT:1.0>/periods.max(),<EOL><NUM_LIT:1.0>/periods.min(),<EOL>durations.size))<EOL><DEDENT><DEDENT>else:<EOL><INDENT>frequencies = minfreq + nparange(nfreq)*stepsize<EOL>periods = <NUM_LIT:1.0>/frequencies<EOL><DEDENT>if nfreq > <NUM_LIT>:<EOL><INDENT>if verbose:<EOL><INDENT>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT><DEDENT>blsresult = blsmodel.power(<EOL>periods*u.day,<EOL>durations*u.day,<EOL>objective=blsobjective,<EOL>method=blsmethod,<EOL>oversample=blsoversample<EOL>)<EOL>lsp = nparray(blsresult.power)<EOL>finitepeakind = npisfinite(lsp)<EOL>finlsp = lsp[finitepeakind]<EOL>finperiods = periods[finitepeakind]<EOL>try:<EOL><INDENT>bestperiodind = npargmax(finlsp)<EOL><DEDENT>except ValueError:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>return {'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':mintransitduration,<EOL>'<STR_LIT>':maxtransitduration,<EOL>'<STR_LIT>':ndurations,<EOL>'<STR_LIT>':blsobjective,<EOL>'<STR_LIT>':blsmethod,<EOL>'<STR_LIT>':blsoversample,<EOL>'<STR_LIT>':blsmintransits,<EOL>'<STR_LIT>':blsfreqfactor,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip,<EOL>'<STR_LIT>':magsarefluxes}}<EOL><DEDENT>sortedlspind = npargsort(finlsp)[::-<NUM_LIT:1>]<EOL>sortedlspperiods = finperiods[sortedlspind]<EOL>sortedlspvals = finlsp[sortedlspind]<EOL>nbestperiods, nbestlspvals, nbestinds, peakcount = (<EOL>[finperiods[bestperiodind]],<EOL>[finlsp[bestperiodind]],<EOL>[bestperiodind],<EOL><NUM_LIT:1><EOL>)<EOL>prevperiod = sortedlspperiods[<NUM_LIT:0>]<EOL>for period, lspval, ind in zip(sortedlspperiods,<EOL>sortedlspvals,<EOL>sortedlspind):<EOL><INDENT>if peakcount == nbestpeaks:<EOL><INDENT>break<EOL><DEDENT>perioddiff = abs(period - prevperiod)<EOL>bestperiodsdiff = [abs(period - x) for x in nbestperiods]<EOL>if (perioddiff > (periodepsilon*prevperiod) and<EOL>all(x > (periodepsilon*period)<EOL>for x in bestperiodsdiff)):<EOL><INDENT>nbestperiods.append(period)<EOL>nbestlspvals.append(lspval)<EOL>nbestinds.append(ind)<EOL>peakcount = peakcount + <NUM_LIT:1><EOL><DEDENT>prevperiod = period<EOL><DEDENT>resultdict = {<EOL>'<STR_LIT>':finperiods[bestperiodind],<EOL>'<STR_LIT>':finlsp[bestperiodind],<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':nbestinds,<EOL>'<STR_LIT>':nbestlspvals,<EOL>'<STR_LIT>':nbestperiods,<EOL>'<STR_LIT>':lsp,<EOL>'<STR_LIT>':frequencies,<EOL>'<STR_LIT>':periods,<EOL>'<STR_LIT>':durations,<EOL>'<STR_LIT>':blsresult,<EOL>'<STR_LIT>':blsmodel,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':nfreq,<EOL>'<STR_LIT>':mintransitduration,<EOL>'<STR_LIT>':maxtransitduration,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':mintransitduration,<EOL>'<STR_LIT>':maxtransitduration,<EOL>'<STR_LIT>':ndurations,<EOL>'<STR_LIT>':blsobjective,<EOL>'<STR_LIT>':blsmethod,<EOL>'<STR_LIT>':blsoversample,<EOL>'<STR_LIT>':blsmintransits,<EOL>'<STR_LIT>':blsfreqfactor,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip,<EOL>'<STR_LIT>':magsarefluxes}<EOL>}<EOL>return resultdict<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>')<EOL>if raiseonfail:<EOL><INDENT>raise<EOL><DEDENT>return {'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':nfreq,<EOL>'<STR_LIT>':mintransitduration,<EOL>'<STR_LIT>':maxtransitduration,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':mintransitduration,<EOL>'<STR_LIT>':maxtransitduration,<EOL>'<STR_LIT>':ndurations,<EOL>'<STR_LIT>':blsobjective,<EOL>'<STR_LIT>':blsmethod,<EOL>'<STR_LIT>':blsoversample,<EOL>'<STR_LIT>':blsmintransits,<EOL>'<STR_LIT>':blsfreqfactor,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip,<EOL>'<STR_LIT>':magsarefluxes}}<EOL><DEDENT><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>')<EOL>return {'<STR_LIT>':npnan,<EOL>'<STR_LIT>':npnan,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':None,<EOL>'<STR_LIT>':mintransitduration,<EOL>'<STR_LIT>':maxtransitduration,<EOL>'<STR_LIT>':'<STR_LIT>',<EOL>'<STR_LIT>':{'<STR_LIT>':startp,<EOL>'<STR_LIT>':endp,<EOL>'<STR_LIT>':stepsize,<EOL>'<STR_LIT>':mintransitduration,<EOL>'<STR_LIT>':maxtransitduration,<EOL>'<STR_LIT>':ndurations,<EOL>'<STR_LIT>':blsobjective,<EOL>'<STR_LIT>':blsmethod,<EOL>'<STR_LIT>':blsoversample,<EOL>'<STR_LIT>':blsmintransits,<EOL>'<STR_LIT>':blsfreqfactor,<EOL>'<STR_LIT>':autofreq,<EOL>'<STR_LIT>':periodepsilon,<EOL>'<STR_LIT>':nbestpeaks,<EOL>'<STR_LIT>':sigclip,<EOL>'<STR_LIT>':magsarefluxes}}<EOL><DEDENT>

Runs the Box Least Squares Fitting Search for transit-shaped signals.

    Based on the version of BLS in Astropy 3.1:
    `astropy.stats.BoxLeastSquares`. If you don't have Astropy 3.1, this module
    will fail to import. Note that by default, this implementation of
    `bls_serial_pfind` doesn't use the `.autoperiod()` function from
    `BoxLeastSquares` but uses the same auto frequency-grid generation as the
    functions in `periodbase.kbls`. If you want to use Astropy's implementation,
    set the value of `autofreq` kwarg to 'astropy'.

    The dict returned from this function contains a `blsmodel` key, which is the
    generated model from Astropy's BLS. Use the `.compute_stats()` method to
    calculate the required stats like SNR, depth, duration, etc.

    Parameters
    ----------

    times,mags,errs : np.array
        The magnitude/flux time-series to search for transits.

    magsarefluxes : bool
        If the input measurement values in `mags` and `errs` are in fluxes, set
        this to True.

    startp,endp : float
        The minimum and maximum periods to consider for the transit search.

    stepsize : float
        The step-size in frequency to use when constructing a frequency grid for
        the period search.

    mintransitduration,maxtransitduration : float
        The minimum and maximum transitdurations (in units of phase) to consider
        for the transit search.

    ndurations : int
        The number of transit durations to use in the period-search.

    autofreq : bool or str
        If this is True, the values of `stepsize` and `nphasebins` will be
        ignored, and these, along with a frequency-grid, will be determined
        based on the following relations::

            nphasebins = int(ceil(2.0/mintransitduration))
            if nphasebins > 3000:
                nphasebins = 3000

            stepsize = 0.25*mintransitduration/(times.max()-times.min())

            minfreq = 1.0/endp
            maxfreq = 1.0/startp
            nfreq = int(ceil((maxfreq - minfreq)/stepsize))

        If this is False, you must set `startp`, `endp`, and `stepsize` as
        appropriate.

        If this is str == 'astropy', will use the
        `astropy.stats.BoxLeastSquares.autoperiod()` function to calculate the
        frequency grid instead of the kbls method.

    blsobjective : {'likelihood','snr'}
        Sets the type of objective to optimize in the `BoxLeastSquares.power()`
        function.

    blsmethod : {'fast','slow'}
        Sets the type of method to use in the `BoxLeastSquares.power()`
        function.

    blsoversample : {'likelihood','snr'}
        Sets the `oversample` kwarg for the `BoxLeastSquares.power()` function.

    blsmintransits : int
        Sets the `min_n_transits` kwarg for the `BoxLeastSquares.autoperiod()`
        function.

    blsfreqfactor : float
        Sets the `frequency_factor` kwarg for the `BoxLeastSquares.autperiod()`
        function.

    periodepsilon : float
        The fractional difference between successive values of 'best' periods
        when sorting by periodogram power to consider them as separate periods
        (as opposed to part of the same periodogram peak). This is used to avoid
        broad peaks in the periodogram and make sure the 'best' periods returned
        are all actually independent.

    nbestpeaks : int
        The number of 'best' peaks to return from the periodogram results,
        starting from the global maximum of the periodogram peak values.

    sigclip : float or int or sequence of two floats/ints or None
        If a single float or int, a symmetric sigma-clip will be performed using
        the number provided as the sigma-multiplier to cut out from the input
        time-series.

        If a list of two ints/floats is provided, the function will perform an
        'asymmetric' sigma-clip. The first element in this list is the sigma
        value to use for fainter flux/mag values; the second element in this
        list is the sigma value to use for brighter flux/mag values. For
        example, `sigclip=[10., 3.]`, will sigclip out greater than 10-sigma
        dimmings and greater than 3-sigma brightenings. Here the meaning of
        "dimming" and "brightening" is set by *physics* (not the magnitude
        system), which is why the `magsarefluxes` kwarg must be correctly set.

        If `sigclip` is None, no sigma-clipping will be performed, and the
        time-series (with non-finite elems removed) will be passed through to
        the output.

    verbose : bool
        If this is True, will indicate progress and details about the frequency
        grid used for the period search.

    raiseonfail : bool
        If True, raises an exception if something goes wrong. Otherwise, returns
        None.

    Returns
    -------

    dict
        This function returns a dict, referred to as an `lspinfo` dict in other
        astrobase functions that operate on periodogram results. This is a
        standardized format across all astrobase period-finders, and is of the
        form below::

            {'bestperiod': the best period value in the periodogram,
             'bestlspval': the periodogram peak associated with the best period,
             'nbestpeaks': the input value of nbestpeaks,
             'nbestlspvals': nbestpeaks-size list of best period peak values,
             'nbestperiods': nbestpeaks-size list of best periods,
             'lspvals': the full array of periodogram powers,
             'frequencies': the full array of frequencies considered,
             'periods': the full array of periods considered,
             'durations': the array of durations used to run BLS,
             'blsresult': Astropy BLS result object (BoxLeastSquaresResult),
             'blsmodel': Astropy BLS BoxLeastSquares object used for work,
             'stepsize': the actual stepsize used,
             'nfreq': the actual nfreq used,
             'durations': the durations array used,
             'mintransitduration': the input mintransitduration,
             'maxtransitduration': the input maxtransitdurations,
             'method':'bls' -> the name of the period-finder method,
             'kwargs':{ dict of all of the input kwargs for record-keeping}}


<EOL>hdulist = pyfits.open(lcfits)<EOL>lchdr, lcdata = hdulist[<NUM_LIT:1>].header, hdulist[<NUM_LIT:1>].data<EOL>lctophdr, lcaperturehdr, lcaperturedata = (hdulist[<NUM_LIT:0>].header,<EOL>hdulist[<NUM_LIT:2>].header,<EOL>hdulist[<NUM_LIT:2>].data)<EOL>hdulist.close()<EOL>hdrinfo = {}<EOL>for key in headerkeys:<EOL><INDENT>if key in lchdr and lchdr[key] is not None:<EOL><INDENT>hdrinfo[key.lower()] = lchdr[key]<EOL><DEDENT>else:<EOL><INDENT>hdrinfo[key.lower()] = None<EOL><DEDENT><DEDENT>ndet = lchdr['<STR_LIT>']<EOL>for key in topkeys:<EOL><INDENT>if key in lctophdr and lctophdr[key] is not None:<EOL><INDENT>hdrinfo[key.lower()] = lctophdr[key]<EOL><DEDENT>else:<EOL><INDENT>hdrinfo[key.lower()] = None<EOL><DEDENT><DEDENT>for key in lcaperturehdr:<EOL><INDENT>if key in lcaperturehdr and lcaperturehdr[key] is not None:<EOL><INDENT>hdrinfo[key.lower()] = lcaperturehdr[key]<EOL><DEDENT>else:<EOL><INDENT>hdrinfo[key.lower()] = None<EOL><DEDENT><DEDENT>if appendto and isinstance(appendto, dict):<EOL><INDENT>lcdict = appendto<EOL>lcdict['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(<EOL>hdrinfo['<STR_LIT>'] + hdrinfo['<STR_LIT>']<EOL>)<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(lcaperturedata)<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(<EOL>(npabs(hdrinfo['<STR_LIT>']) +<EOL>npabs(hdrinfo['<STR_LIT>']))*<NUM_LIT>/<NUM_LIT><EOL>)<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(ndet)<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'].append(hdrinfo['<STR_LIT>'])<EOL>for key in datakeys:<EOL><INDENT>if key.lower() in lcdict:<EOL><INDENT>lcdict[key.lower()] = (<EOL>npconcatenate((lcdict[key.lower()], lcdata[key]))<EOL>)<EOL><DEDENT><DEDENT>for key in sapkeys:<EOL><INDENT>if key.lower() in lcdict['<STR_LIT>']:<EOL><INDENT>sapflux_median = np.nanmedian(lcdata['<STR_LIT>'])<EOL>if normalize and key == '<STR_LIT>':<EOL><INDENT>thislcdata = lcdata[key] / sapflux_median<EOL><DEDENT>elif normalize and key == '<STR_LIT>':<EOL><INDENT>thislcdata = lcdata[key] / sapflux_median<EOL><DEDENT>elif normalize and key == '<STR_LIT>':<EOL><INDENT>thislcdata = lcdata[key] / sapflux_median<EOL><DEDENT>elif normalize and key == '<STR_LIT>':<EOL><INDENT>thislcdata = lcdata[key] / sapflux_median<EOL><DEDENT>else:<EOL><INDENT>thislcdata = lcdata[key]<EOL><DEDENT>lcdict['<STR_LIT>'][key.lower()] = (<EOL>np.concatenate((lcdict['<STR_LIT>'][key.lower()], thislcdata))<EOL>)<EOL><DEDENT><DEDENT>for key in pdckeys:<EOL><INDENT>if key.lower() in lcdict['<STR_LIT>']:<EOL><INDENT>pdcsap_flux_median = np.nanmedian(lcdata['<STR_LIT>'])<EOL>if normalize and key == '<STR_LIT>':<EOL><INDENT>thislcdata = lcdata[key] / pdcsap_flux_median<EOL><DEDENT>elif normalize and key == '<STR_LIT>':<EOL><INDENT>thislcdata = lcdata[key] / pdcsap_flux_median<EOL><DEDENT>else:<EOL><INDENT>thislcdata = lcdata[key]<EOL><DEDENT>lcdict['<STR_LIT>'][key.lower()] = (<EOL>np.concatenate((lcdict['<STR_LIT>'][key.lower()], thislcdata))<EOL>)<EOL><DEDENT><DEDENT>lcdict['<STR_LIT>'] = npconcatenate(<EOL>(lcdict['<STR_LIT>'],<EOL>npfull_like(lcdata['<STR_LIT>'],<EOL>hdrinfo['<STR_LIT>']))<EOL>)<EOL>lcdict['<STR_LIT>'] = npconcatenate(<EOL>(lcdict['<STR_LIT>'],<EOL>npfull_like(lcdata['<STR_LIT>'],<EOL>hdrinfo['<STR_LIT>']))<EOL>)<EOL>lcdict['<STR_LIT>'] = npconcatenate(<EOL>(lcdict['<STR_LIT>'],<EOL>npfull_like(lcdata['<STR_LIT>'],<EOL>hdrinfo['<STR_LIT>']))<EOL>)<EOL>lcdict['<STR_LIT>'] = npconcatenate(<EOL>(lcdict['<STR_LIT>'],<EOL>npfull_like(lcdata['<STR_LIT>'],<EOL>hdrinfo['<STR_LIT>']))<EOL>)<EOL>lcdict['<STR_LIT>'] = npconcatenate(<EOL>(lcdict['<STR_LIT>'],<EOL>npfull_like(lcdata['<STR_LIT>'],<EOL>hdrinfo['<STR_LIT>']))<EOL>)<EOL>lcdict['<STR_LIT>'] = npconcatenate(<EOL>(lcdict['<STR_LIT>'],<EOL>npfull_like(lcdata['<STR_LIT>'],<EOL>hdrinfo['<STR_LIT>']))<EOL>)<EOL>lcdict['<STR_LIT>'] = npconcatenate(<EOL>(lcdict['<STR_LIT>'],<EOL>npfull_like(lcdata['<STR_LIT>'],<EOL>hdrinfo['<STR_LIT>']))<EOL>)<EOL><DEDENT>else:<EOL><INDENT>lcdict = {<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],  <EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT:object>'],<EOL>'<STR_LIT>':{<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>'] + hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[lcaperturedata],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[(npabs(hdrinfo['<STR_LIT>']) +<EOL>npabs(hdrinfo['<STR_LIT>']))*<NUM_LIT>/<NUM_LIT>],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[ndet],<EOL>},<EOL>'<STR_LIT>':{<EOL>'<STR_LIT>':hdrinfo['<STR_LIT:object>'],  <EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>},<EOL>'<STR_LIT>':{<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>},<EOL>'<STR_LIT>':{},<EOL>'<STR_LIT>':{},<EOL>}<EOL>for key in datakeys:<EOL><INDENT>lcdict[key.lower()] = lcdata[key]<EOL><DEDENT>for key in sapkeys:<EOL><INDENT>lcdict['<STR_LIT>'][key.lower()] = lcdata[key]<EOL><DEDENT>for key in pdckeys:<EOL><INDENT>lcdict['<STR_LIT>'][key.lower()] = lcdata[key]<EOL><DEDENT>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:time>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:time>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:time>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:time>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:time>'],<EOL>lcdict['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:time>'],<EOL>lcdict['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:time>'],<EOL>lcdict['<STR_LIT>'][<NUM_LIT:0>])<EOL>if normalize:<EOL><INDENT>sapflux_median = np.nanmedian(lcdict['<STR_LIT>']['<STR_LIT>'])<EOL>pdcsap_flux_median = np.nanmedian(lcdict['<STR_LIT>']['<STR_LIT>'])<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = (<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] /<EOL>sapflux_median<EOL>)<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = (<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] /<EOL>sapflux_median<EOL>)<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = (<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] /<EOL>sapflux_median<EOL>)<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = (<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] /<EOL>sapflux_median<EOL>)<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = (<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] /<EOL>pdcsap_flux_median<EOL>)<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = (<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] /<EOL>pdcsap_flux_median<EOL>)<EOL><DEDENT><DEDENT>lcdict['<STR_LIT>'] = (<EOL>[x.lower() for x in datakeys] +<EOL>['<STR_LIT>' % x.lower() for x in sapkeys] +<EOL>['<STR_LIT>' % x.lower() for x in pdckeys] +<EOL>['<STR_LIT>','<STR_LIT>','<STR_LIT>',<EOL>'<STR_LIT>','<STR_LIT>','<STR_LIT>']<EOL>)<EOL>return lcdict<EOL>

This extracts the light curve from a single Kepler or K2 LC FITS file.

    This works on the light curves available at MAST:

    - `kplr{kepid}-{somedatething}_llc.fits` files from the Kepler mission
    - `ktwo{epicid}-c{campaign}_llc.fits` files from the K2 mission

    Parameters
    ----------

    lcfits : str
        The filename of a MAST Kepler/K2 light curve FITS file.

    headerkeys : list
        A list of FITS header keys that will be extracted from the FITS light
        curve file. These describe the observations. The default value for this
        is given in `LCHEADERKEYS` above.

    datakeys : list
        A list of FITS column names that correspond to the auxiliary
        measurements in the light curve. The default is `LCDATAKEYS` above.

    sapkeys : list
        A list of FITS column names that correspond to the SAP flux
        measurements in the light curve. The default is `LCSAPKEYS` above.

    pdckeys : list
        A list of FITS column names that correspond to the PDC flux
        measurements in the light curve. The default is `LCPDCKEYS` above.

    topkeys : list
        A list of FITS header keys that describe the object in the light
        curve. The default is `LCTOPKEYS` above.

    apkeys : list
        A list of FITS header keys that describe the flux measurement apertures
        used by the Kepler/K2 pipeline. The default is `LCAPERTUREKEYS` above.

    appendto : lcdict or None
        If appendto is an `lcdict`, will append measurements of this `lcdict` to
        that `lcdict`. This is used for consolidating light curves for the same
        object across different files (quarters). The appending does not care
        about the time order. To consolidate light curves in time order, use
        `consolidate_kepler_fitslc` below.

    normalize : bool
        If True, then each component light curve's SAP_FLUX and PDCSAP_FLUX
        measurements will be normalized to 1.0 by dividing out the median flux
        for the component light curve.

    Returns
    -------

    lcdict
        Returns an `lcdict` (this is useable by most astrobase functions for LC
        processing).


kepmag = <NUM_LIT> - <NUM_LIT>*nplog10(keplerflux/f12)<EOL>return kepmag<EOL>

This converts the Kepler flux in electrons/sec to Kepler magnitude.

    The kepler mag/flux relation is::

        fkep = (10.0**(-0.4*(kepmag - 12.0)))*f12
        f12 = 1.74e5 # electrons/sec

    Parameters
    ----------

    keplerflux : float or array-like
        The flux value(s) to convert to magnitudes.

    f12 : float
        The flux value in the Kepler band corresponding to Kepler mag = 12.0.

    Returns
    -------

    np.array
        Magnitudes in the Kepler band corresponding to the input `keplerflux`
        flux value(s).


<EOL>hdulist = pyfits.open(lcfits)<EOL>lchdr, lcdata = hdulist[<NUM_LIT:1>].header, hdulist[<NUM_LIT:1>].data<EOL>lctophdr = hdulist[<NUM_LIT:0>].header<EOL>hdulist.close()<EOL>hdrinfo = {}<EOL>ndet = lchdr['<STR_LIT>']<EOL>for key in SFFTOPKEYS:<EOL><INDENT>if key in lctophdr and lctophdr[key] is not None:<EOL><INDENT>hdrinfo[key.lower()] = lctophdr[key]<EOL><DEDENT>else:<EOL><INDENT>hdrinfo[key.lower()] = None<EOL><DEDENT><DEDENT>for key in SFFHEADERKEYS:<EOL><INDENT>if key in lchdr and lchdr[key] is not None:<EOL><INDENT>hdrinfo[key.lower()] = lchdr[key]<EOL><DEDENT>else:<EOL><INDENT>hdrinfo[key.lower()] = None<EOL><DEDENT><DEDENT>lcdict = {<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT:object>'],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':{<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>'] + hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[None],<EOL>'<STR_LIT>':[None],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[ndet],<EOL>},<EOL>'<STR_LIT>':{<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>'<STR_LIT>':hdrinfo['<STR_LIT>'],<EOL>},<EOL>'<STR_LIT>':{<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>'<STR_LIT>':[hdrinfo['<STR_LIT>']],<EOL>},<EOL>}<EOL>for key in SFFDATAKEYS:<EOL><INDENT>lcdict[key.lower()] = lcdata[key]<EOL><DEDENT>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:t>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:t>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:t>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:t>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:t>'],<EOL>lcdict['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:t>'],<EOL>lcdict['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = npfull_like(lcdict['<STR_LIT:t>'],<EOL>lcdict['<STR_LIT>'][<NUM_LIT:0>])<EOL>lcdict['<STR_LIT>'] = (<EOL>[x.lower() for x in SFFDATAKEYS] +<EOL>['<STR_LIT>','<STR_LIT>','<STR_LIT>','<STR_LIT>','<STR_LIT>','<STR_LIT>','<STR_LIT>']<EOL>)<EOL>return lcdict<EOL>

This reads a K2 SFF (Vandenberg+ 2014) light curve into an `lcdict`.

    Use this with the light curves from the K2 SFF project at MAST.

    Parameters
    ----------

    lcfits : str
        The filename of the FITS light curve file downloaded from MAST.

    Returns
    -------

    lcdict
        Returns an `lcdict` (this is useable by most astrobase functions for LC
        processing).


times, fluxes, background, background_err = (lcdict['<STR_LIT:time>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'],<EOL>lcdict['<STR_LIT>']['<STR_LIT>'])<EOL>xcc = lcdict[xccol]<EOL>ycc = lcdict[yccol]<EOL>flags = lcdict['<STR_LIT>']<EOL>if filterflags:<EOL><INDENT>nbefore = times.size<EOL>filterind = flags == <NUM_LIT:0><EOL>times = times[filterind]<EOL>fluxes = fluxes[filterind]<EOL>background = background[filterind]<EOL>background_err = background_err[filterind]<EOL>xcc = xcc[filterind]<EOL>ycc = ycc[filterind]<EOL>flags = flags[filterind]<EOL>nafter = times.size<EOL>LOGINFO('<STR_LIT>'<EOL>% (nbefore, nafter))<EOL><DEDENT>find = (npisfinite(xcc) & npisfinite(ycc) &<EOL>npisfinite(times) & npisfinite(fluxes) &<EOL>npisfinite(background) & npisfinite(background_err))<EOL>nbefore = times.size<EOL>times = times[find]<EOL>fluxes = fluxes[find]<EOL>background = background[find]<EOL>background_err = background_err[find]<EOL>xcc = xcc[find]<EOL>ycc = ycc[find]<EOL>flags = flags[find]<EOL>nafter = times.size<EOL>LOGINFO('<STR_LIT>'<EOL>% (nbefore, nafter))<EOL>if (timestoignore and<EOL>isinstance(timestoignore, list) and<EOL>len(timestoignore) > <NUM_LIT:0>):<EOL><INDENT>exclind = npfull_like(times,True)<EOL>nbefore = times.size<EOL>for ignoretime in timestoignore:<EOL><INDENT>time0, time1 = ignoretime[<NUM_LIT:0>], ignoretime[<NUM_LIT:1>]<EOL>thismask = (times > time0) & (times < time1)<EOL>exclind = exclind & thismask<EOL><DEDENT>times = times[exclind]<EOL>fluxes = fluxes[exclind]<EOL>background = background[exclind]<EOL>background_err = background_err[exclind]<EOL>xcc = xcc[exclind]<EOL>ycc = ycc[exclind]<EOL>flags = flags[exclind]<EOL>nafter = times.size<EOL>LOGINFO('<STR_LIT>'<EOL>% (nbefore, nafter))<EOL><DEDENT>smoothedfluxes = median_filter(fluxes, size=epdsmooth)<EOL>initcoeffs = npones(<NUM_LIT:11>)<EOL>leastsqfit = leastsq(_epd_residual,<EOL>initcoeffs,<EOL>args=(smoothedfluxes,<EOL>xcc, ycc,<EOL>background, background_err))<EOL>if leastsqfit[-<NUM_LIT:1>] in (<NUM_LIT:1>,<NUM_LIT:2>,<NUM_LIT:3>,<NUM_LIT:4>):<EOL><INDENT>fitcoeffs = leastsqfit[<NUM_LIT:0>]<EOL>epdfit = _epd_function(fitcoeffs,<EOL>fluxes,<EOL>xcc,<EOL>ycc,<EOL>background,<EOL>background_err)<EOL>epdfluxes = npmedian(fluxes) + fluxes - epdfit<EOL>if writetodict:<EOL><INDENT>lcdict['<STR_LIT>'] = {}<EOL>lcdict['<STR_LIT>']['<STR_LIT:time>'] = times<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = fluxes<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = epdfluxes<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = epdfit<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = background<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = background_err<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = xcc<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = ycc<EOL>lcdict['<STR_LIT>']['<STR_LIT>'] = flags<EOL>for newcol in ['<STR_LIT>','<STR_LIT>',<EOL>'<STR_LIT>','<STR_LIT>',<EOL>'<STR_LIT>','<STR_LIT>',<EOL>'<STR_LIT>','<STR_LIT>',<EOL>'<STR_LIT>']:<EOL><INDENT>if newcol not in lcdict['<STR_LIT>']:<EOL><INDENT>lcdict['<STR_LIT>'].append(newcol)<EOL><DEDENT><DEDENT><DEDENT>return times, epdfluxes, fitcoeffs, epdfit<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>')<EOL>return None, None, None, None<EOL><DEDENT>

This runs EPD on the Kepler light curve.

    Following Huang et al. 2015, we fit the following EPD function to a smoothed
    light curve, and then subtract it to obtain EPD corrected magnitudes::

        f = c0 +
            c1*sin(2*pi*x) + c2*cos(2*pi*x) + c3*sin(2*pi*y) + c4*cos(2*pi*y) +
            c5*sin(4*pi*x) + c6*cos(4*pi*x) + c7*sin(4*pi*y) + c8*cos(4*pi*y) +
            c9*bgv + c10*bge

    By default, this function removes points in the Kepler LC that have ANY
    quality flags set.

    Parameters
    ----------

    lcdict : lcdict
        An `lcdict` produced by `consolidate_kepler_fitslc` or
        `read_kepler_fitslc`.

    xcol,ycol : str
        Indicates the x and y coordinate column names to use from the Kepler LC
        in the EPD fit.

    timestoignore : list of tuples
        This is of the form::

            [(time1_start, time1_end), (time2_start, time2_end), ...]

        and indicates the start and end times to mask out of the final
        lcdict. Use this to remove anything that wasn't caught by the quality
        flags.

    filterflags : bool
        If True, will remove any measurements that have non-zero quality flags
        present. This usually indicates an issue with the instrument or
        spacecraft.

    writetodict : bool
        If writetodict is True, adds the following columns to the lcdict::

            epd_time = time array
            epd_sapflux = uncorrected flux before EPD
            epd_epdsapflux = corrected flux after EPD
            epd_epdsapcorr = EPD flux corrections
            epd_bkg = background array
            epd_bkg_err = background errors array
            epd_xcc = xcoord array
            epd_ycc = ycoord array
            epd_quality = quality flag array

        and updates the 'columns' list in the lcdict as well.

    epdsmooth : int
        Sets the number of light curve points to smooth over when generating the
        EPD fit function.

    Returns
    -------

    tuple
        Returns a tuple of the form: (times, epdfluxes, fitcoeffs, epdfit)


def _epd_residual(coeffs, fluxes, xcc, ycc, bgv, bge):

f = _epd_function(coeffs, fluxes, xcc, ycc, bgv, bge)<EOL>residual = fluxes - f<EOL>return residual<EOL>

This is the residual function to minimize using scipy.optimize.leastsq.

    Parameters
    ----------

    coeffs : array-like of floats
        Contains the EPD coefficients that will be used to generate the EPD fit
        function.

    fluxes : array-like
        The flux measurement array being used.

    xcc,ycc : array-like
        Arrays of the x and y coordinates associated with each measurement in
        `fluxes`.

    bgv,bge : array-like
        Arrays of the flux background value and the flux background error
        associated with each measurement in `fluxes`.

    Returns
    -------

    np.array
        Contains the fit function residual evaluated at each flux measurement
        value.


def pre(self, command, output_dir, vars):

<EOL>vars['<STR_LIT>'] = '<STR_LIT>'<EOL>vars['<STR_LIT>'] = time.strftime('<STR_LIT>', time.localtime())<EOL>


def prop_power(self, propulsion_eff=<NUM_LIT>, sea_margin=<NUM_LIT>):

PP = (<NUM_LIT:1> + sea_margin) * self.resistance() * self.speed/propulsion_eff<EOL>return PP<EOL>

Total propulsion power of the ship.

:param propulsion_eff: Shaft efficiency of the ship
:param sea_margin: Sea margin take account of interaction between ship and the sea, e.g. wave
:return: Watts shaft propulsion power of the ship


def residual_resistance_coef(slenderness, prismatic_coef, froude_number):

Cr = cr(slenderness, prismatic_coef, froude_number)<EOL>if math.isnan(Cr):<EOL><INDENT>Cr = cr_nearest(slenderness, prismatic_coef, froude_number)<EOL><DEDENT>return Cr<EOL>

Residual resistance coefficient estimation from slenderness function, prismatic coefficient and Froude number.

:param slenderness: Slenderness coefficient dimensionless :math:`L/(∇^{1/3})` where L is length of ship, ∇ is displacement
:param prismatic_coef: Prismatic coefficient dimensionless :math:`∇/(L\cdot A_m)` where L is length of ship, ∇ is displacement Am is midsection area of the ship
:param froude_number: Froude number of the ship dimensionless
:return: Residual resistance of the ship


return reynolds_number(self.length, self.speed)<EOL>

Return Reynold number of the ship

:return: Reynold number of the ship


self.total_resistance_coef = frictional_resistance_coef(self.length, self.speed) +residual_resistance_coef(self.slenderness_coefficient,<EOL>self.prismatic_coefficient,<EOL>froude_number(self.speed, self.length))<EOL>RT = <NUM_LIT:1> / <NUM_LIT:2> * self.total_resistance_coef * <NUM_LIT> * self.surface_area * self.speed ** <NUM_LIT:2><EOL>return RT<EOL>

Return resistance of the vehicle.

:return: newton the resistance of the ship


g = <NUM_LIT>  <EOL>Fr = speed / np.sqrt(g * length)<EOL>return Fr<EOL>

Froude number utility function that return Froude number for vehicle at specific length and speed.

:param speed: m/s speed of the vehicle
:param length: metres length of the vehicle
:return: Froude number of the vehicle (dimensionless)


return str1[:i] + str2 + str1[i:]<EOL>

Insert a string in the middle of another string
:param str1: the original string
:param str2: the string to be inserted
:param i: the index of the insertion position
:return: the resulting string


def format_datetime(t: datetime = None):

return (datetime.now() if t is None else t).strftime('<STR_LIT>')<EOL>

Format a datetime object into yyyy-MM-dd hh:mm:ss
:param t: datetime object, default: now
:return: the formatted string


def dict_format_type(d, source, formatter, include_list=True):

if not isinstance(d, dict):<EOL><INDENT>if isinstance(d, source):<EOL><INDENT>return formatter(d)<EOL><DEDENT>else:<EOL><INDENT>return d<EOL><DEDENT><DEDENT>else:<EOL><INDENT>dd = dict()<EOL>for key, value in d.items():<EOL><INDENT>if include_list and isinstance(value, list):<EOL><INDENT>dd[key] = [dict_format_type(i, source, formatter) for i in value]<EOL><DEDENT>elif isinstance(value, dict):<EOL><INDENT>dd[key] = dict_format_type(value, source, formatter)<EOL><DEDENT>elif isinstance(value, source):<EOL><INDENT>dd[key] = formatter(value)<EOL><DEDENT>else:<EOL><INDENT>dd[key] = value<EOL><DEDENT><DEDENT>return dd<EOL><DEDENT>

Replace the values of a dict with certain type to other values
:param d: the dictionary
:param source: the source type, e.g., int
:param formatter: the formatter method, e.g., return the string format of an int
:param include_list: whether list should be formatted, otherwise list will be considered as source type
:return: formatted dictionary


return '<STR_LIT>'.join(random.SystemRandom().choice(string.digits) for _ in range(n))<EOL>

Generate a random string from 0-9
:param n: length of the string
:return: the random string


h = list()<EOL>for i in range(len(d)):<EOL><INDENT>heappush(h, (-d[i][k] if reverse else d[i][k], i))<EOL><DEDENT>r = list()<EOL>while len(r) < n and len(h) > <NUM_LIT:0>:<EOL><INDENT>_, i = heappop(h)<EOL>r.append(d[i].copy())<EOL><DEDENT>return r<EOL>

Return top n of a dictionary list sorted by key
:param d: dictionary list
:param k: key
:param n: top n
:param reverse: whether the value should be reversed
:return: top n of the sorted dictionary list


def progress(count, total, prefix='<STR_LIT>', suffix='<STR_LIT>', length=<NUM_LIT>):

bar_len = length<EOL>filled_len = int(round(bar_len * count / float(total)))<EOL>percents = round(<NUM_LIT> * count / float(total), <NUM_LIT:1>)<EOL>bar = '<STR_LIT:=>' * filled_len + '<STR_LIT:->' * (bar_len - filled_len)<EOL>sys.stdout.write('<STR_LIT>' % (prefix, bar, percents, '<STR_LIT:%>', '<STR_LIT:U+0020>' + suffix))<EOL>sys.stdout.flush()<EOL>

Show a progress bar
:param count: current progress
:param total: total progress
:param prefix: prefix shown before the progress bar
:param suffix: suffix shown after the progress bar
:param length: length of the progress bar, default: 60
:return: none


return '<STR_LIT>'.join(random.SystemRandom().choice(string.ascii_letters) for _ in range(n))<EOL>

Generate a random string from a-zA-Z
:param n: length of the string
:return: the random string


for i in range(len(d)):<EOL><INDENT>if d[i][k] == v:<EOL><INDENT>return i<EOL><DEDENT><DEDENT>return None<EOL>

Search dictionary list by key and value
:param d: dictionary list
:param k: key
:param v: value
:return: the index of the first dictionary in the array with the specific key / value


c = a.copy()<EOL>for j in range(len(b)):<EOL><INDENT>flag = False<EOL>for i in range(len(c)):<EOL><INDENT>if c[i][k] == b[j][k]:<EOL><INDENT>c[i] = b[j].copy()<EOL>flag = True<EOL><DEDENT><DEDENT>if not flag:<EOL><INDENT>c.append(b[j].copy())<EOL><DEDENT><DEDENT>return c<EOL>

Merge two dictionary lists
:param a: original list
:param b: alternative list, element will replace the one in original list with same key
:param k: key
:return: the merged list


dd = dict()<EOL>for key, value in d.items():<EOL><INDENT>if not key == k:<EOL><INDENT>if isinstance(value, dict):<EOL><INDENT>dd[key] = dict_remove_key(value, k)<EOL><DEDENT>elif isinstance(value, list):<EOL><INDENT>dd[key] = [dict_remove_key(i, k) for i in value]<EOL><DEDENT>else:<EOL><INDENT>dd[key] = value<EOL><DEDENT><DEDENT><DEDENT>return dd<EOL>

Recursively remove a key from a dict
:param d: the dictionary
:param k: key which should be removed
:return: formatted dictionary