def pdw_period_find(times,<EOL>mags,<EOL>errs,<EOL>autofreq=True,<EOL>init_p=None,<EOL>end_p=None,<EOL>f_step=<NUM_LIT>,<EOL>phasebinsize=None,<EOL>sigclip=<NUM_LIT>,<EOL>nworkers=None,<EOL>verbose=False):
<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))