<EOL>if wcsfrom is None:<EOL><INDENT>hdulist = pyfits.open(fitsfile)<EOL>img, hdr = hdulist[fitsext].data, hdulist[fitsext].header<EOL>hdulist.close()<EOL>frameshape = (hdr['<STR_LIT>'], hdr['<STR_LIT>'])<EOL>w = WCS(hdr)<EOL><DEDENT>elif os.path.exists(wcsfrom):<EOL><INDENT>hdulist = pyfits.open(fitsfile)<EOL>img, hdr = hdulist[fitsext].data, hdulist[fitsext].header<EOL>hdulist.close()<EOL>frameshape = (hdr['<STR_LIT>'], hdr['<STR_LIT>'])<EOL>w = WCS(wcsfrom)<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>' %<EOL>fitsfile)<EOL>return None<EOL><DEDENT>if findersize is None:<EOL><INDENT>fig = plt.figure(figsize=(frameshape[<NUM_LIT:0>]/<NUM_LIT>,<EOL>frameshape[<NUM_LIT:1>]/<NUM_LIT>))<EOL><DEDENT>else:<EOL><INDENT>fig = plt.figure(figsize=findersize)<EOL><DEDENT>if (overlay_zoomcontain and<EOL>overlay_ra is not None and<EOL>overlay_decl is not None):<EOL><INDENT>finder_coordlimits = [overlay_ra.min()-<NUM_LIT>/<NUM_LIT>,<EOL>overlay_ra.max()+<NUM_LIT>/<NUM_LIT>,<EOL>overlay_decl.min()-<NUM_LIT>/<NUM_LIT>,<EOL>overlay_decl.max()+<NUM_LIT>/<NUM_LIT>]<EOL><DEDENT>if finder_coordlimits and isinstance(finder_coordlimits, (list,tuple)):<EOL><INDENT>minra, maxra, mindecl, maxdecl = finder_coordlimits<EOL>cntra, cntdecl = (minra + maxra)/<NUM_LIT>, (mindecl + maxdecl)/<NUM_LIT><EOL>pixelcoords = w.all_world2pix([[minra, mindecl],<EOL>[maxra, maxdecl],<EOL>[cntra, cntdecl]],<NUM_LIT:1>)<EOL>x1, y1, x2, y2 = (int(pixelcoords[<NUM_LIT:0>,<NUM_LIT:0>]),<EOL>int(pixelcoords[<NUM_LIT:0>,<NUM_LIT:1>]),<EOL>int(pixelcoords[<NUM_LIT:1>,<NUM_LIT:0>]),<EOL>int(pixelcoords[<NUM_LIT:1>,<NUM_LIT:1>]))<EOL>xmin = x1 if x1 < x2 else x2<EOL>xmax = x2 if x2 > x1 else x1<EOL>ymin = y1 if y1 < y2 else y2<EOL>ymax = y2 if y2 > y1 else y1<EOL>whdr = w.to_header()<EOL>whdr['<STR_LIT>'] = (xmax - xmin)/<NUM_LIT:2><EOL>whdr['<STR_LIT>'] = (ymax - ymin)/<NUM_LIT:2><EOL>whdr['<STR_LIT>'] = cntra<EOL>whdr['<STR_LIT>'] = cntdecl<EOL>whdr['<STR_LIT>'] = xmax - xmin<EOL>whdr['<STR_LIT>'] = ymax - ymin<EOL>w = WCS(whdr)<EOL><DEDENT>else:<EOL><INDENT>xmin, xmax, ymin, ymax = <NUM_LIT:0>, hdr['<STR_LIT>'], <NUM_LIT:0>, hdr['<STR_LIT>']<EOL><DEDENT>fig.add_subplot(<NUM_LIT>,projection=w)<EOL>if scale is not None and stretch is not None:<EOL><INDENT>norm = ImageNormalize(img,<EOL>interval=scale,<EOL>stretch=stretch)<EOL>plt.imshow(img[ymin:ymax,xmin:xmax],<EOL>origin='<STR_LIT>',<EOL>cmap=colormap,<EOL>norm=norm)<EOL><DEDENT>else:<EOL><INDENT>plt.imshow(img[ymin:ymax,xmin:xmax],<EOL>origin='<STR_LIT>',<EOL>cmap=colormap)<EOL><DEDENT>if grid:<EOL><INDENT>plt.grid(color=gridcolor,ls='<STR_LIT>',lw=<NUM_LIT:1.0>)<EOL><DEDENT>if overlay_ra is not None and overlay_decl is not None:<EOL><INDENT>our_pltopts = dict(<EOL>transform=plt.gca().get_transform('<STR_LIT>'),<EOL>marker='<STR_LIT:o>',<EOL>markersize=<NUM_LIT>,<EOL>markerfacecolor='<STR_LIT:none>',<EOL>markeredgewidth=<NUM_LIT>,<EOL>markeredgecolor='<STR_LIT>',<EOL>rasterized=True,<EOL>linestyle='<STR_LIT:none>'<EOL>)<EOL>if overlay_pltopts is not None and isinstance(overlay_pltopts,<EOL>dict):<EOL><INDENT>our_pltopts.update(overlay_pltopts)<EOL><DEDENT>plt.gca().set_autoscale_on(False)<EOL>plt.gca().plot(overlay_ra, overlay_decl,<EOL>**our_pltopts)<EOL><DEDENT>plt.xlabel('<STR_LIT>')<EOL>plt.ylabel('<STR_LIT>')<EOL>xax = plt.gca().coords[<NUM_LIT:0>]<EOL>yax = plt.gca().coords[<NUM_LIT:1>]<EOL>yax.set_major_formatter('<STR_LIT>')<EOL>xax.set_major_formatter('<STR_LIT>')<EOL>plt.savefig(outfile, dpi=<NUM_LIT>)<EOL>plt.close('<STR_LIT:all>')<EOL>return outfile<EOL>

This makes a finder chart for a given FITS with an optional object
    position overlay.

    Parameters
    ----------

    fitsfile : str
        `fitsfile` is the FITS file to use to make the finder chart.

    outfile : str
        `outfile` is the name of the output file. This can be a png or pdf or
        whatever else matplotlib can write given a filename and extension.

    fitsext : int
        Sets the FITS extension in `fitsfile` to use to extract the image array
        from.

    wcsfrom : str or None
        If `wcsfrom` is None, the WCS to transform the RA/Dec to pixel x/y will
        be taken from the FITS header of `fitsfile`. If this is not None, it
        must be a FITS or similar file that contains a WCS header in its first
        extension.

    scale : astropy.visualization.Interval object
        `scale` sets the normalization for the FITS pixel values. This is an
        astropy.visualization Interval object.
        See http://docs.astropy.org/en/stable/visualization/normalization.html
        for details on `scale` and `stretch` objects.

    stretch : astropy.visualization.Stretch object
        `stretch` sets the stretch function for mapping FITS pixel values to
        output pixel values. This is an astropy.visualization Stretch object.
        See http://docs.astropy.org/en/stable/visualization/normalization.html
        for details on `scale` and `stretch` objects.

    colormap : matplotlib Colormap object
        `colormap` is a matplotlib color map object to use for the output image.

    findersize : None or tuple of two ints
        If `findersize` is None, the output image size will be set by the NAXIS1
        and NAXIS2 keywords in the input `fitsfile` FITS header. Otherwise,
        `findersize` must be a tuple with the intended x and y size of the image
        in inches (all output images will use a DPI = 100).

    finder_coordlimits : list of four floats or None
        If not None, `finder_coordlimits` sets x and y limits for the plot,
        effectively zooming it in if these are smaller than the dimensions of
        the FITS image. This should be a list of the form: [minra, maxra,
        mindecl, maxdecl] all in decimal degrees.

    overlay_ra, overlay_decl : np.array or None
        `overlay_ra` and `overlay_decl` are ndarrays containing the RA and Dec
        values to overplot on the image as an overlay. If these are both None,
        then no overlay will be plotted.

    overlay_pltopts : dict
        `overlay_pltopts` controls how the overlay points will be plotted. This
        a dict with standard matplotlib marker, etc. kwargs as key-val pairs,
        e.g. 'markersize', 'markerfacecolor', etc. The default options make red
        outline circles at the location of each object in the overlay.

    overlay_zoomcontain : bool
        `overlay_zoomcontain` controls if the finder chart will be zoomed to
        just contain the overlayed points. Everything outside the footprint of
        these points will be discarded.

    grid : bool
        `grid` sets if a grid will be made on the output image.

    gridcolor : str
        `gridcolor` sets the color of the grid lines. This is a usual matplotib
        color spec string.

    Returns
    -------

    str or None
        The filename of the generated output image if successful. None
        otherwise.


def plot_periodbase_lsp(lspinfo, outfile=None, plotdpi=<NUM_LIT:100>):

<EOL>if isinstance(lspinfo,str) and os.path.exists(lspinfo):<EOL><INDENT>LOGINFO('<STR_LIT>' % lspinfo)<EOL>with open(lspinfo,'<STR_LIT:rb>') as infd:<EOL><INDENT>lspinfo = pickle.load(infd)<EOL><DEDENT><DEDENT>try:<EOL><INDENT>periods = lspinfo['<STR_LIT>']<EOL>lspvals = lspinfo['<STR_LIT>']<EOL>bestperiod = lspinfo['<STR_LIT>']<EOL>lspmethod = lspinfo['<STR_LIT>']<EOL>plt.plot(periods, lspvals)<EOL>plt.xscale('<STR_LIT>',basex=<NUM_LIT:10>)<EOL>plt.xlabel('<STR_LIT>')<EOL>plt.ylabel(PLOTYLABELS[lspmethod])<EOL>plottitle = '<STR_LIT>' % (METHODSHORTLABELS[lspmethod],<EOL>bestperiod)<EOL>plt.title(plottitle)<EOL>for bestperiod, bestpeak in zip(lspinfo['<STR_LIT>'],<EOL>lspinfo['<STR_LIT>']):<EOL><INDENT>plt.annotate('<STR_LIT>' % bestperiod,<EOL>xy=(bestperiod, bestpeak), xycoords='<STR_LIT:data>',<EOL>xytext=(<NUM_LIT:0.0>,<NUM_LIT>), textcoords='<STR_LIT>',<EOL>arrowprops=dict(arrowstyle="<STR_LIT>"),fontsize='<STR_LIT>')<EOL><DEDENT>plt.grid(color='<STR_LIT>',<EOL>alpha=<NUM_LIT>,<EOL>zorder=<NUM_LIT:0>,<EOL>linewidth=<NUM_LIT:1.0>,<EOL>linestyle='<STR_LIT::>')<EOL>if outfile and isinstance(outfile, str):<EOL><INDENT>if outfile.endswith('<STR_LIT>'):<EOL><INDENT>plt.savefig(outfile,bbox_inches='<STR_LIT>',dpi=plotdpi)<EOL><DEDENT>else:<EOL><INDENT>plt.savefig(outfile,bbox_inches='<STR_LIT>')<EOL><DEDENT>plt.close()<EOL>return os.path.abspath(outfile)<EOL><DEDENT>elif dispok:<EOL><INDENT>plt.show()<EOL>plt.close()<EOL>return<EOL><DEDENT>else:<EOL><INDENT>LOGWARNING('<STR_LIT>'<EOL>'<STR_LIT>')<EOL>outfile = '<STR_LIT>'<EOL>plt.savefig(outfile,bbox_inches='<STR_LIT>',dpi=plotdpi)<EOL>plt.close()<EOL>return os.path.abspath(outfile)<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>')<EOL>return<EOL><DEDENT>

Makes a plot of periodograms obtained from `periodbase` functions.

    This takes the output dict produced by any `astrobase.periodbase`
    period-finder function or a pickle filename containing such a dict and makes
    a periodogram plot.

    Parameters
    ----------

    lspinfo : dict or str
        If lspinfo is a dict, it must be a dict produced by an
        `astrobase.periodbase` period-finder function or a dict from your own
        period-finder function or routine that is of the form below with at
        least these keys::

            {'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 `METHODLABELS` dict above,
             '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}

        If lspinfo is a str, then it must be a path to a pickle file that
        contains a dict of the form described above.

    outfile : str or None
        If this is a str, will write the periodogram plot to the file specified
        by this string. If this is None, will write to a file called
        'lsp-plot.png' in the current working directory.

    plotdpi : int
        Sets the resolution in DPI of the output periodogram plot PNG file.

    Returns
    -------

    str
        Absolute path to the periodogram plot file created.


if radians:<EOL><INDENT>wrapped = angle % (<NUM_LIT>*pi_value)<EOL>if wrapped < <NUM_LIT:0.0>:<EOL><INDENT>wrapped = <NUM_LIT>*pi_value + wrapped<EOL><DEDENT><DEDENT>else:<EOL><INDENT>wrapped = angle % <NUM_LIT><EOL>if wrapped < <NUM_LIT:0.0>:<EOL><INDENT>wrapped = <NUM_LIT> + wrapped<EOL><DEDENT><DEDENT>return wrapped<EOL>

Wraps the input angle to 360.0 degrees.

    Parameters
    ----------

    angle : float
        The angle to wrap around 360.0 deg.

    radians : bool
        If True, will assume that the input is in radians. The output will then
        also be in radians.

    Returns
    -------

    float
        Wrapped angle. If radians is True: input is assumed to be in radians,
        output is also in radians.


if decimal_value < <NUM_LIT:0>:<EOL><INDENT>negative = True<EOL>dec_val = fabs(decimal_value)<EOL><DEDENT>else:<EOL><INDENT>negative = False<EOL>dec_val = decimal_value<EOL><DEDENT>degrees = trunc(dec_val)<EOL>minutes_deg = dec_val - degrees<EOL>minutes_mm = minutes_deg * <NUM_LIT><EOL>minutes_out = trunc(minutes_mm)<EOL>seconds = (minutes_mm - minutes_out)*<NUM_LIT><EOL>if negative:<EOL><INDENT>degrees = degrees<EOL>return '<STR_LIT:->', degrees, minutes_out, seconds<EOL><DEDENT>else:<EOL><INDENT>return '<STR_LIT:+>', degrees, minutes_out, seconds<EOL><DEDENT>

Converts from decimal degrees (for declination coords) to DD:MM:SS.

    Parameters
    ----------

    decimal_value : float
        A decimal value to convert to degrees, minutes, seconds sexagesimal
        format.

    Returns
    -------

    tuple
        A four element tuple is returned: (sign, HH, MM, SS.ssss...)


<EOL>if decimal_value < <NUM_LIT:0>:<EOL><INDENT>dec_wrapped = <NUM_LIT> + decimal_value<EOL><DEDENT>else:<EOL><INDENT>dec_wrapped = decimal_value<EOL><DEDENT>dec_hours = dec_wrapped/<NUM_LIT><EOL>if dec_hours < <NUM_LIT:0>:<EOL><INDENT>negative = True<EOL>dec_val = fabs(dec_hours)<EOL><DEDENT>else:<EOL><INDENT>negative = False<EOL>dec_val = dec_hours<EOL><DEDENT>hours = trunc(dec_val)<EOL>minutes_hrs = dec_val - hours<EOL>minutes_mm = minutes_hrs * <NUM_LIT><EOL>minutes_out = trunc(minutes_mm)<EOL>seconds = (minutes_mm - minutes_out)*<NUM_LIT><EOL>if negative:<EOL><INDENT>hours = -hours<EOL>return hours, minutes_out, seconds<EOL><DEDENT>else:<EOL><INDENT>return hours, minutes_out, seconds<EOL><DEDENT>

Converts from decimal degrees (for RA coords) to HH:MM:SS.

    Parameters
    ----------

    decimal_value : float
        A decimal value to convert to hours, minutes, seconds. Negative values
        will be wrapped around 360.0.

    Returns
    -------

    tuple
        A three element tuple is returned: (HH, MM, SS.ssss...)


if '<STR_LIT::>' in hms_string:<EOL><INDENT>separator = '<STR_LIT::>'<EOL><DEDENT>else:<EOL><INDENT>separator = '<STR_LIT:U+0020>'<EOL><DEDENT>hh, mm, ss = hms_string.split(separator)<EOL>return int(hh), int(mm), float(ss)<EOL>

Converts a string of the form HH:MM:SS or HH MM SS to a tuple of the form
    (HH, MM, SS).

    Parameters
    ----------

    hms_string : str
        A RA coordinate string of the form 'HH:MM:SS.sss' or 'HH MM SS.sss'.

    Returns
    -------

    tuple
        A three element tuple is returned (HH, MM, SS.ssss...)


if '<STR_LIT::>' in dms_string:<EOL><INDENT>separator = '<STR_LIT::>'<EOL><DEDENT>else:<EOL><INDENT>separator = '<STR_LIT:U+0020>'<EOL><DEDENT>sign_dd, mm, ss = dms_string.split(separator)<EOL>if sign_dd.startswith('<STR_LIT:+>') or sign_dd.startswith('<STR_LIT:->'):<EOL><INDENT>sign, dd = sign_dd[<NUM_LIT:0>], sign_dd[<NUM_LIT:1>:]<EOL><DEDENT>else:<EOL><INDENT>sign, dd = '<STR_LIT:+>', sign_dd<EOL><DEDENT>return sign, int(dd), int(mm), float(ss)<EOL>

Converts a string of the form [+-]DD:MM:SS or [+-]DD MM SS to a tuple of
    the form (sign, DD, MM, SS).

    Parameters
    ----------

    dms_string : str
        A declination coordinate string of the form '[+-]DD:MM:SS.sss' or
        '[+-]DD MM SS.sss'. The sign in front of DD is optional. If it's not
        there, this function will assume that the coordinate string is a
        positive value.

    Returns
    -------

    tuple
        A four element tuple of the form: (sign, DD, MM, SS.ssss...).


return hms_to_decimal(*hms_str_to_tuple(hms_string))<EOL>

Converts a HH:MM:SS string to decimal degrees.

    Parameters
    ----------

    hms_string : str
        A right ascension coordinate string of the form: 'HH:MM:SS.sss'
        or 'HH MM SS.sss'.

    Returns
    -------

    float
        The RA value in decimal degrees (wrapped around 360.0 deg if necessary.)


return dms_to_decimal(*dms_str_to_tuple(dms_string))<EOL>

Converts a DD:MM:SS string to decimal degrees.

    Parameters
    ----------

    dms_string : str
        A declination coordinate string of the form: '[+-]DD:MM:SS.sss'
        or '[+-]DD MM SS.sss'.

    Returns
    -------

    float
        The declination value in decimal degrees.


def hms_to_decimal(hours, minutes, seconds, returndeg=True):

if hours > <NUM_LIT>:<EOL><INDENT>return None<EOL><DEDENT>else:<EOL><INDENT>dec_hours = fabs(hours) + fabs(minutes)/<NUM_LIT> + fabs(seconds)/<NUM_LIT><EOL>if returndeg:<EOL><INDENT>dec_deg = dec_hours*<NUM_LIT><EOL>if dec_deg < <NUM_LIT:0>:<EOL><INDENT>dec_deg = dec_deg + <NUM_LIT><EOL><DEDENT>dec_deg = dec_deg % <NUM_LIT><EOL>return dec_deg<EOL><DEDENT>else:<EOL><INDENT>return dec_hours<EOL><DEDENT><DEDENT>

Converts from HH, MM, SS to a decimal value.

    Parameters
    ----------

    hours : int
        The HH part of a RA coordinate.

    minutes : int
        The MM part of a RA coordinate.

    seconds : float
        The SS.sss part of a RA coordinate.

    returndeg : bool
        If this is True, then will return decimal degrees as the output.
        If this is False, then will return decimal HOURS as the output.
        Decimal hours are sometimes used in FITS headers.

    Returns
    -------

    float
        The right ascension value in either decimal degrees or decimal hours
        depending on `returndeg`.


def dms_to_decimal(sign, degrees, minutes, seconds):

dec_deg = fabs(degrees) + fabs(minutes)/<NUM_LIT> + fabs(seconds)/<NUM_LIT><EOL>if sign == '<STR_LIT:->':<EOL><INDENT>return -dec_deg<EOL><DEDENT>else:<EOL><INDENT>return dec_deg<EOL><DEDENT>

Converts from DD:MM:SS to a decimal value.

    Parameters
    ----------

    sign : {'+', '-', ''}
        The sign part of a Dec coordinate.

    degrees : int
        The DD part of a Dec coordinate.

    minutes : int
        The MM part of a Dec coordinate.

    seconds : float
        The SS.sss part of a Dec coordinate.

    Returns
    -------

    float
        The declination value in decimal degrees.


def great_circle_dist(ra1, dec1, ra2, dec2):

<EOL>in_ra1 = ra1 % <NUM_LIT><EOL>in_ra1 = in_ra1 + <NUM_LIT>*(in_ra1 < <NUM_LIT:0.0>)<EOL>in_ra2 = ra2 % <NUM_LIT><EOL>in_ra2 = in_ra2 + <NUM_LIT>*(in_ra1 < <NUM_LIT:0.0>)<EOL>ra1_rad, dec1_rad = np.deg2rad(in_ra1), np.deg2rad(dec1)<EOL>ra2_rad, dec2_rad = np.deg2rad(in_ra2), np.deg2rad(dec2)<EOL>del_dec2 = (dec2_rad - dec1_rad)/<NUM_LIT><EOL>del_ra2 = (ra2_rad - ra1_rad)/<NUM_LIT><EOL>sin_dist = np.sqrt(np.sin(del_dec2) * np.sin(del_dec2) +<EOL>np.cos(dec1_rad) * np.cos(dec2_rad) *<EOL>np.sin(del_ra2) * np.sin(del_ra2))<EOL>dist_rad = <NUM_LIT> * np.arcsin(sin_dist)<EOL>return np.rad2deg(dist_rad)*<NUM_LIT><EOL>

Calculates the great circle angular distance between two coords.

    This calculates the great circle angular distance in arcseconds between two
    coordinates (ra1,dec1) and (ra2,dec2). This is basically a clone of GCIRC
    from the IDL Astrolib.

    Parameters
    ----------

    ra1,dec1 : float or array-like
        The first coordinate's right ascension and declination value(s) in
        decimal degrees.

    ra2,dec2 : float or array-like
        The second coordinate's right ascension and declination value(s) in
        decimal degrees.

    Returns
    -------

    float or array-like
        Great circle distance between the two coordinates in arseconds.

    Notes
    -----

    If (`ra1`, `dec1`) is scalar and (`ra2`, `dec2`) is scalar: the result is a
    float distance in arcseconds.

    If (`ra1`, `dec1`) is scalar and (`ra2`, `dec2`) is array-like: the result
    is an np.array with distance in arcseconds between (`ra1`, `dec1`) and each
    element of (`ra2`, `dec2`).

    If (`ra1`, `dec1`) is array-like and (`ra2`, `dec2`) is scalar: the result
    is an np.array with distance in arcseconds between (`ra2`, `dec2`) and each
    element of (`ra1`, `dec1`).

    If (`ra1`, `dec1`) and (`ra2`, `dec2`) are both array-like: the result is an
    np.array with the pair-wise distance in arcseconds between each element of
    the two coordinate lists. In this case, if the input array-likes are not the
    same length, then excess elements of the longer one will be ignored.


def xmatch_basic(ra1, dec1, ra2, dec2, match_radius=<NUM_LIT>):

min_dist_arcsec = np.min(great_circle_dist(ra1,dec1,ra2,dec2))<EOL>if (min_dist_arcsec < match_radius):<EOL><INDENT>return (True,min_dist_arcsec)<EOL><DEDENT>else:<EOL><INDENT>return (False,min_dist_arcsec)<EOL><DEDENT>

Finds the closest object in (`ra2`, `dec2`) to scalar coordinate pair
    (`ra1`, `dec1`) and returns the distance in arcseconds.

    This is a quick matcher that uses the `great_circle_dist` function to find
    the closest object in (`ra2`, `dec2`) within `match_radius` arcseconds to
    (`ra1`, `dec1`). (`ra1`, `dec1`) must be a scalar pair, while
    (`ra2`, `dec2`) must be array-likes of the same lengths.

    Parameters
    ----------

    ra1,dec1 : float
        Coordinate of the object to find matches to. In decimal degrees.

    ra2,dec2 : array-like
        The coordinates that will be searched for matches. In decimal degrees.

    match_radius : float
        The match radius in arcseconds to use for the match.

    Returns
    -------

    tuple
        A two element tuple like the following::

            (True -> no match found or False -> found a match,
             minimum distance between target and list in arcseconds)


def xmatch_neighbors(ra1, dec1,<EOL>ra2, dec2,<EOL>match_radius=<NUM_LIT>,<EOL>includeself=False,<EOL>sortresults=True):

dist = great_circle_dist(ra1,dec1,ra2,dec2)<EOL>if includeself:<EOL><INDENT>match_dist_ind = np.where(dist < match_radius)<EOL><DEDENT>else:<EOL><INDENT>match_dist_ind = np.where((dist < match_radius) & (dist > <NUM_LIT:0.1>))<EOL><DEDENT>if len(match_dist_ind) > <NUM_LIT:0>:<EOL><INDENT>match_dists = dist[match_dist_ind]<EOL>dist_sort_ind = np.argsort(match_dists)<EOL>if sortresults:<EOL><INDENT>match_dist_ind = (match_dist_ind[<NUM_LIT:0>])[dist_sort_ind]<EOL><DEDENT>min_dist = np.min(match_dists)<EOL>return (True,min_dist,match_dist_ind,match_dists[dist_sort_ind])<EOL><DEDENT>else:<EOL><INDENT>return (False,)<EOL><DEDENT>

Finds the closest objects in (`ra2`, `dec2`) to scalar coordinate pair
    (`ra1`, `dec1`) and returns the indices of the objects that match.

    This is a quick matcher that uses the `great_circle_dist` function to find
    the closest object in (`ra2`, `dec2`) within `match_radius` arcseconds to
    (`ra1`, `dec1`). (`ra1`, `dec1`) must be a scalar pair, while
    (`ra2`, `dec2`) must be array-likes of the same lengths.

    Parameters
    ----------

    ra1,dec1 : float
        Coordinate of the object to find matches to. In decimal degrees.

    ra2,dec2 : array-like
        The coordinates that will be searched for matches. In decimal degrees.

    match_radius : float
        The match radius in arcseconds to use for the match.

    includeself : bool
        If this is True, the object itself will be included in the match
        results.

    sortresults : bool
        If this is True, the match indices will be sorted by distance.

    Returns
    -------

    tuple
        A tuple like the following is returned::

            (True -> matches found or False -> no matches found,
             minimum distance between target and list,
             np.array of indices where list of coordinates is
             closer than `match_radius` arcseconds from the target,
             np.array of distances in arcseconds)


<EOL>cosdecl = np.cos(np.radians(decl))<EOL>sindecl = np.sin(np.radians(decl))<EOL>cosra = np.cos(np.radians(ra))<EOL>sinra = np.sin(np.radians(ra))<EOL>xyz = np.column_stack((cosra*cosdecl,sinra*cosdecl, sindecl))<EOL>kdt = sps.cKDTree(xyz,copy_data=True)<EOL>return kdt<EOL>

This makes a `scipy.spatial.CKDTree` on (`ra`, `decl`).

    Parameters
    ----------

    ra,decl : array-like
        The right ascension and declination coordinate pairs in decimal degrees.

    Returns
    -------

    `scipy.spatial.CKDTree`
        The cKDTRee object generated by this function is returned and can be
        used to run various spatial queries.


cosdecl = np.cos(np.radians(declcenter))<EOL>sindecl = np.sin(np.radians(declcenter))<EOL>cosra = np.cos(np.radians(racenter))<EOL>sinra = np.sin(np.radians(racenter))<EOL>xyzdist = <NUM_LIT> * np.sin(np.radians(searchradiusdeg)/<NUM_LIT>)<EOL>kdtindices = kdtree.query_ball_point([cosra*cosdecl,<EOL>sinra*cosdecl,<EOL>sindecl],<EOL>xyzdist,<EOL>n_jobs=conesearchworkers)<EOL>return kdtindices<EOL>

This does a cone-search around (`racenter`, `declcenter`) in `kdtree`.

    Parameters
    ----------

    kdtree : scipy.spatial.CKDTree
        This is a kdtree object generated by the `make_kdtree` function.

    racenter,declcenter : float or array-like
        This is the center coordinate to run the cone-search around in decimal
        degrees. If this is an np.array, will search for all coordinate pairs in
        the array.

    searchradiusdeg : float
        The search radius to use for the cone-search in decimal degrees.

    conesearchworkers : int
        The number of parallel workers to launch for the cone-search.

    Returns
    -------

    list or np.array of lists
        If (`racenter`, `declcenter`) is a single coordinate, this will return a
        list of the indices of the matching objects in the kdtree. If
        (`racenter`, `declcenter`) are array-likes, this will return an object
        array containing lists of matching object indices for each coordinate
        searched.


ext_cosdecl = np.cos(np.radians(extdecl))<EOL>ext_sindecl = np.sin(np.radians(extdecl))<EOL>ext_cosra = np.cos(np.radians(extra))<EOL>ext_sinra = np.sin(np.radians(extra))<EOL>ext_xyz = np.column_stack((ext_cosra*ext_cosdecl,<EOL>ext_sinra*ext_cosdecl,<EOL>ext_sindecl))<EOL>ext_xyzdist = <NUM_LIT> * np.sin(np.radians(xmatchdistdeg)/<NUM_LIT>)<EOL>our_kdt = kdtree<EOL>ext_kdt = sps.cKDTree(ext_xyz)<EOL>extkd_matchinds = our_kdt.query_ball_tree(ext_kdt, ext_xyzdist)<EOL>ext_matchinds = []<EOL>kdt_matchinds = []<EOL>for extind, mind in enumerate(extkd_matchinds):<EOL><INDENT>if len(mind) > <NUM_LIT:0>:<EOL><INDENT>kdt_matchinds.append(extind)<EOL>if closestonly:<EOL><INDENT>ext_matchinds.append(mind[<NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>ext_matchinds.append(mind)<EOL><DEDENT><DEDENT><DEDENT>return kdt_matchinds, ext_matchinds<EOL>

This cross-matches between `kdtree` and (`extra`, `extdecl`) arrays.

    Returns the indices of the kdtree and the indices of extra, extdecl that
    xmatch successfully.

    Parameters
    ----------

    kdtree : scipy.spatial.CKDTree
        This is a kdtree object generated by the `make_kdtree` function.

    extra,extdecl : array-like
        These are np.arrays of 'external' coordinates in decimal degrees that
        will be cross-matched against the objects in `kdtree`.

    xmatchdistdeg : float
        The match radius to use for the cross-match in decimal degrees.

    closestonly : bool
        If closestonly is True, then this function returns only the closest
        matching indices in (extra, extdecl) for each object in kdtree if there
        are any matches. Otherwise, it returns a list of indices in (extra,
        extdecl) for all matches within xmatchdistdeg between kdtree and (extra,
        extdecl).

    Returns
    -------

    tuple of lists
        Returns a tuple of the form::

            (list of `kdtree` indices matching to external objects,
             list of all `extra`/`extdecl` indices that match to each
             element in `kdtree` within the specified cross-match distance)


def total_proper_motion(pmra, pmdecl, decl):

pm = np.sqrt( pmdecl*pmdecl + pmra*pmra*np.cos(np.radians(decl)) *<EOL>np.cos(np.radians(decl)) )<EOL>return pm<EOL>

This calculates the total proper motion of an object.

    Parameters
    ----------

    pmra : float or array-like
        The proper motion(s) in right ascension, measured in mas/yr.

    pmdecl : float or array-like
        The proper motion(s) in declination, measured in mas/yr.

    decl : float or array-like
        The declination of the object(s) in decimal degrees.

    Returns
    -------

    float or array-like
        The total proper motion(s) of the object(s) in mas/yr.


rpm = mag + <NUM_LIT>*np.log10(propermotion/<NUM_LIT>)<EOL>return rpm<EOL>

This calculates the reduced proper motion using the mag measurement
    provided.

    Parameters
    ----------

    mag : float or array-like
        The magnitude(s) to use to calculate the reduced proper motion(s).

    propermotion : float or array-like
        The total proper motion of the object(s). Use the `total_proper_motion`
        function to calculate this if you have `pmra`, `pmdecl`, and `decl`
        values. `propermotion` should be in mas/yr.

    Returns
    -------

    float or array-like
        The reduced proper motion for the object(s). This is effectively a
        measure of the absolute magnitude in the band provided.


def equatorial_to_galactic(ra, decl, equinox='<STR_LIT>'):

<EOL>radecl = SkyCoord(ra=ra*u.degree, dec=decl*u.degree, equinox=equinox)<EOL>gl = radecl.galactic.l.degree<EOL>gb = radecl.galactic.b.degree<EOL>return gl, gb<EOL>

This converts from equatorial coords to galactic coords.

    Parameters
    ----------

    ra : float or array-like
        Right ascension values(s) in decimal degrees.

    decl : float or array-like
        Declination value(s) in decimal degrees.

    equinox : str
        The equinox that the coordinates are measured at. This must be
        recognizable by Astropy's `SkyCoord` class.

    Returns
    -------

    tuple of (float, float) or tuple of (np.array, np.array)
        The galactic coordinates (l, b) for each element of the input
        (`ra`, `decl`).


gal = SkyCoord(gl*u.degree, gl*u.degree, frame='<STR_LIT>')<EOL>transformed = gal.transform_to('<STR_LIT>')<EOL>return transformed.ra.degree, transformed.dec.degree<EOL>

This converts from galactic coords to equatorial coordinates.

    Parameters
    ----------

    gl : float or array-like
        Galactic longitude values(s) in decimal degrees.

    gb : float or array-like
        Galactic latitude value(s) in decimal degrees.

    Returns
    -------

    tuple of (float, float) or tuple of (np.array, np.array)
        The equatorial coordinates (RA, DEC) for each element of the input
        (`gl`, `gb`) in decimal degrees. These are reported in the ICRS frame.


def xieta_from_radecl(inra, indecl,<EOL>incenterra, incenterdecl,<EOL>deg=True):

if deg:<EOL><INDENT>ra = np.radians(inra)<EOL>decl = np.radians(indecl)<EOL>centerra = np.radians(incenterra)<EOL>centerdecl = np.radians(incenterdecl)<EOL><DEDENT>else:<EOL><INDENT>ra = inra<EOL>decl = indecl<EOL>centerra = incenterra<EOL>centerdecl = incenterdecl<EOL><DEDENT>cdecc = np.cos(centerdecl)<EOL>sdecc = np.sin(centerdecl)<EOL>crac = np.cos(centerra)<EOL>srac = np.sin(centerra)<EOL>uu = np.cos(decl)*np.cos(ra)<EOL>vv = np.cos(decl)*np.sin(ra)<EOL>ww = np.sin(decl)<EOL>uun = uu*cdecc*crac + vv*cdecc*srac + ww*sdecc<EOL>vvn = -uu*srac + vv*crac<EOL>wwn = -uu*sdecc*crac - vv*sdecc*srac + ww*cdecc<EOL>denom = vvn*vvn + wwn*wwn<EOL>aunn = np.zeros_like(uun)<EOL>aunn[uun >= <NUM_LIT:1.0>] = <NUM_LIT:0.0><EOL>aunn[uun < <NUM_LIT:1.0>] = np.arccos(uun)<EOL>xi, eta = np.zeros_like(aunn), np.zeros_like(aunn)<EOL>xi[(aunn <= <NUM_LIT:0.0>) | (denom <= <NUM_LIT:0.0>)] = <NUM_LIT:0.0><EOL>eta[(aunn <= <NUM_LIT:0.0>) | (denom <= <NUM_LIT:0.0>)] = <NUM_LIT:0.0><EOL>sdenom = np.sqrt(denom)<EOL>xi[(aunn > <NUM_LIT:0.0>) | (denom > <NUM_LIT:0.0>)] = aunn*vvn/sdenom<EOL>eta[(aunn > <NUM_LIT:0.0>) | (denom > <NUM_LIT:0.0>)] = aunn*wwn/sdenom<EOL>if deg:<EOL><INDENT>return np.degrees(xi), np.degrees(eta)<EOL><DEDENT>else:<EOL><INDENT>return xi, eta<EOL><DEDENT>

This returns the image-plane projected xi-eta coords for inra, indecl.

    Parameters
    ----------

    inra,indecl : array-like
        The equatorial coordinates to get the xi, eta coordinates for in decimal
        degrees or radians.

    incenterra,incenterdecl : float
        The center coordinate values to use to calculate the plane-projected
        coordinates around.

    deg : bool
        If this is True, the input angles are assumed to be in degrees and the
        output is in degrees as well.

    Returns
    -------

    tuple of np.arrays
        This is the (`xi`, `eta`) coordinate pairs corresponding to the
        image-plane projected coordinates for each pair of input equatorial
        coordinates in (`inra`, `indecl`).


try:<EOL><INDENT>formatinfo = get_lcformat(lcformat,<EOL>use_lcformat_dir=lcformatdir)<EOL>if formatinfo:<EOL><INDENT>(dfileglob, readerfunc,<EOL>dtimecols, dmagcols, derrcols,<EOL>magsarefluxes, normfunc) = formatinfo<EOL><DEDENT>else:<EOL><INDENT>LOGERROR("<STR_LIT>")<EOL>return None<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION("<STR_LIT>")<EOL>return None<EOL><DEDENT>try:<EOL><INDENT>lcdict = readerfunc(lcfile)<EOL>if ( (isinstance(lcdict, (list, tuple))) and<EOL>(isinstance(lcdict[<NUM_LIT:0>], dict)) ):<EOL><INDENT>lcdict = lcdict[<NUM_LIT:0>]<EOL><DEDENT>resultdict = {'<STR_LIT>':lcdict['<STR_LIT>'],<EOL>'<STR_LIT:info>':lcdict['<STR_LIT>'],<EOL>'<STR_LIT>':os.path.basename(lcfile)}<EOL>coordfeat = starfeatures.coord_features(lcdict['<STR_LIT>'])<EOL>colorfeat = starfeatures.color_features(<EOL>lcdict['<STR_LIT>'],<EOL>deredden=deredden,<EOL>custom_bandpasses=custom_bandpasses<EOL>)<EOL>colorclass = starfeatures.color_classification(colorfeat,<EOL>coordfeat)<EOL>nbrfeat = starfeatures.neighbor_gaia_features(lcdict['<STR_LIT>'],<EOL>kdtree,<EOL>neighbor_radius_arcsec)<EOL>if nbrfeat['<STR_LIT>'].size > <NUM_LIT:0>:<EOL><INDENT>nbrfeat['<STR_LIT>'] = objlist[nbrfeat['<STR_LIT>']]<EOL>nbrfeat['<STR_LIT>'] = objlist[<EOL>nbrfeat['<STR_LIT>']<EOL>]<EOL>nbrfeat['<STR_LIT>'] = lcflist[<EOL>nbrfeat['<STR_LIT>']<EOL>]<EOL><DEDENT>else:<EOL><INDENT>nbrfeat['<STR_LIT>'] = np.array([])<EOL>nbrfeat['<STR_LIT>'] = np.array([])<EOL>nbrfeat['<STR_LIT>'] = np.array([])<EOL><DEDENT>resultdict.update(coordfeat)<EOL>resultdict.update(colorfeat)<EOL>resultdict.update(colorclass)<EOL>resultdict.update(nbrfeat)<EOL>outfile = os.path.join(outdir,<EOL>'<STR_LIT>' %<EOL>squeeze(resultdict['<STR_LIT>']).replace('<STR_LIT:U+0020>','<STR_LIT:->'))<EOL>with open(outfile, '<STR_LIT:wb>') as outfd:<EOL><INDENT>pickle.dump(resultdict, outfd, protocol=<NUM_LIT:4>)<EOL><DEDENT>return outfile<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>' %<EOL>(os.path.basename(lcfile), e))<EOL>return None<EOL><DEDENT>

This runs the functions from :py:func:`astrobase.varclass.starfeatures`
    on a single light curve file.

    Parameters
    ----------

    lcfile : str
        This is the LC file to extract star features for.

    outdir : str
        This is the directory to write the output pickle to.

    kdtree: scipy.spatial.cKDTree
        This is a `scipy.spatial.KDTree` or `cKDTree` used to calculate neighbor
        proximity features. This is for the light curve catalog this object is
        in.

    objlist : np.array
        This is a Numpy array of object IDs in the same order as the
        `kdtree.data` np.array. This is for the light curve catalog this object
        is in.

    lcflist : np.array
        This is a Numpy array of light curve filenames in the same order as
        `kdtree.data`. This is for the light curve catalog this object is in.

    neighbor_radius_arcsec : float
        This indicates the radius in arcsec to search for neighbors for this
        object using the light curve catalog's `kdtree`, `objlist`, `lcflist`,
        and in GAIA.

    deredden : bool
        This controls if the colors and any color classifications will be
        dereddened using 2MASS DUST.

    custom_bandpasses : dict or None
        This is a dict used to define any custom bandpasses in the
        `in_objectinfo` dict you want to make this function aware of and
        generate colors for. Use the format below for this dict::

            {
            '<bandpass_key_1>':{'dustkey':'<twomass_dust_key_1>',
                                'label':'<band_label_1>'
                                'colors':[['<bandkey1>-<bandkey2>',
                                           '<BAND1> - <BAND2>'],
                                          ['<bandkey3>-<bandkey4>',
                                           '<BAND3> - <BAND4>']]},
            .
            ...
            .
            '<bandpass_key_N>':{'dustkey':'<twomass_dust_key_N>',
                                'label':'<band_label_N>'
                                'colors':[['<bandkey1>-<bandkey2>',
                                           '<BAND1> - <BAND2>'],
                                          ['<bandkey3>-<bandkey4>',
                                           '<BAND3> - <BAND4>']]},
            }

        Where:

        `bandpass_key` is a key to use to refer to this bandpass in the
        `objectinfo` dict, e.g. 'sdssg' for SDSS g band

        `twomass_dust_key` is the key to use in the 2MASS DUST result table for
        reddening per band-pass. For example, given the following DUST result
        table (using http://irsa.ipac.caltech.edu/applications/DUST/)::

            |Filter_name|LamEff |A_over_E_B_V_SandF|A_SandF|A_over_E_B_V_SFD|A_SFD|
            |char       |float  |float             |float  |float           |float|
            |           |microns|                  |mags   |                |mags |
             CTIO U       0.3734              4.107   0.209            4.968 0.253
             CTIO B       0.4309              3.641   0.186            4.325 0.221
             CTIO V       0.5517              2.682   0.137            3.240 0.165
            .
            .
            ...

        The `twomass_dust_key` for 'vmag' would be 'CTIO V'. If you want to
        skip DUST lookup and want to pass in a specific reddening magnitude
        for your bandpass, use a float for the value of
        `twomass_dust_key`. If you want to skip DUST lookup entirely for
        this bandpass, use None for the value of `twomass_dust_key`.

        `band_label` is the label to use for this bandpass, e.g. 'W1' for
        WISE-1 band, 'u' for SDSS u, etc.

        The 'colors' list contains color definitions for all colors you want
        to generate using this bandpass. this list contains elements of the
        form::

            ['<bandkey1>-<bandkey2>','<BAND1> - <BAND2>']

        where the the first item is the bandpass keys making up this color,
        and the second item is the label for this color to be used by the
        frontends. An example::

            ['sdssu-sdssg','u - g']

    lcformat : str
        This is the `formatkey` associated with your light curve format, which
        you previously passed in to the `lcproc.register_lcformat`
        function. This will be used to look up how to find and read the light
        curves specified in `basedir` or `use_list_of_filenames`.

    lcformatdir : str or None
        If this is provided, gives the path to a directory when you've stored
        your lcformat description JSONs, other than the usual directories lcproc
        knows to search for them in. Use this along with `lcformat` to specify
        an LC format JSON file that's not currently registered with lcproc.

    Returns
    -------

    str
        Path to the output pickle containing all of the star features for this
        object.


try:<EOL><INDENT>(lcfile, outdir, kdtree, objlist,<EOL>lcflist, neighbor_radius_arcsec,<EOL>deredden, custom_bandpasses, lcformat, lcformatdir) = task<EOL>return get_starfeatures(lcfile, outdir,<EOL>kdtree, objlist, lcflist,<EOL>neighbor_radius_arcsec,<EOL>deredden=deredden,<EOL>custom_bandpasses=custom_bandpasses,<EOL>lcformat=lcformat,<EOL>lcformatdir=lcformatdir)<EOL><DEDENT>except Exception as e:<EOL><INDENT>return None<EOL><DEDENT>


<EOL>if not os.path.exists(outdir):<EOL><INDENT>os.makedirs(outdir)<EOL><DEDENT>if maxobjects:<EOL><INDENT>lclist = lclist[:maxobjects]<EOL><DEDENT>with open(lc_catalog_pickle, '<STR_LIT:rb>') as infd:<EOL><INDENT>kdt_dict = pickle.load(infd)<EOL><DEDENT>kdt = kdt_dict['<STR_LIT>']<EOL>objlist = kdt_dict['<STR_LIT>']['<STR_LIT>']<EOL>objlcfl = kdt_dict['<STR_LIT>']['<STR_LIT>']<EOL>tasks = [(x, outdir, kdt, objlist, objlcfl,<EOL>neighbor_radius_arcsec,<EOL>deredden, custom_bandpasses,<EOL>lcformat, lcformatdir) for x in lclist]<EOL>for task in tqdm(tasks):<EOL><INDENT>result = _starfeatures_worker(task)<EOL><DEDENT>return result<EOL>

This drives the `get_starfeatures` function for a collection of LCs.

    Parameters
    ----------

    lclist : list of str
        The list of light curve file names to process.

    outdir : str
        The output directory where the results will be placed.

    lc_catalog_pickle : str
        The path to a catalog containing at a dict with least:

        - an object ID array accessible with `dict['objects']['objectid']`

        - an LC filename array accessible with `dict['objects']['lcfname']`

        - a `scipy.spatial.KDTree` or `cKDTree` object to use for finding
          neighbors for each object accessible with `dict['kdtree']`

        A catalog pickle of the form needed can be produced using
        :py:func:`astrobase.lcproc.catalogs.make_lclist` or
        :py:func:`astrobase.lcproc.catalogs.filter_lclist`.

    neighbor_radius_arcsec : float
        This indicates the radius in arcsec to search for neighbors for this
        object using the light curve catalog's `kdtree`, `objlist`, `lcflist`,
        and in GAIA.

    maxobjects : int
        The number of objects to process from `lclist`.

    deredden : bool
        This controls if the colors and any color classifications will be
        dereddened using 2MASS DUST.

    custom_bandpasses : dict or None
        This is a dict used to define any custom bandpasses in the
        `in_objectinfo` dict you want to make this function aware of and
        generate colors for. Use the format below for this dict::

            {
            '<bandpass_key_1>':{'dustkey':'<twomass_dust_key_1>',
                                'label':'<band_label_1>'
                                'colors':[['<bandkey1>-<bandkey2>',
                                           '<BAND1> - <BAND2>'],
                                          ['<bandkey3>-<bandkey4>',
                                           '<BAND3> - <BAND4>']]},
            .
            ...
            .
            '<bandpass_key_N>':{'dustkey':'<twomass_dust_key_N>',
                                'label':'<band_label_N>'
                                'colors':[['<bandkey1>-<bandkey2>',
                                           '<BAND1> - <BAND2>'],
                                          ['<bandkey3>-<bandkey4>',
                                           '<BAND3> - <BAND4>']]},
            }

        Where:

        `bandpass_key` is a key to use to refer to this bandpass in the
        `objectinfo` dict, e.g. 'sdssg' for SDSS g band

        `twomass_dust_key` is the key to use in the 2MASS DUST result table for
        reddening per band-pass. For example, given the following DUST result
        table (using http://irsa.ipac.caltech.edu/applications/DUST/)::

            |Filter_name|LamEff |A_over_E_B_V_SandF|A_SandF|A_over_E_B_V_SFD|A_SFD|
            |char       |float  |float             |float  |float           |float|
            |           |microns|                  |mags   |                |mags |
             CTIO U       0.3734              4.107   0.209            4.968 0.253
             CTIO B       0.4309              3.641   0.186            4.325 0.221
             CTIO V       0.5517              2.682   0.137            3.240 0.165
            .
            .
            ...

        The `twomass_dust_key` for 'vmag' would be 'CTIO V'. If you want to
        skip DUST lookup and want to pass in a specific reddening magnitude
        for your bandpass, use a float for the value of
        `twomass_dust_key`. If you want to skip DUST lookup entirely for
        this bandpass, use None for the value of `twomass_dust_key`.

        `band_label` is the label to use for this bandpass, e.g. 'W1' for
        WISE-1 band, 'u' for SDSS u, etc.

        The 'colors' list contains color definitions for all colors you want
        to generate using this bandpass. this list contains elements of the
        form::

            ['<bandkey1>-<bandkey2>','<BAND1> - <BAND2>']

        where the the first item is the bandpass keys making up this color,
        and the second item is the label for this color to be used by the
        frontends. An example::

            ['sdssu-sdssg','u - g']

    lcformat : str
        This is the `formatkey` associated with your light curve format, which
        you previously passed in to the `lcproc.register_lcformat`
        function. This will be used to look up how to find and read the light
        curves specified in `basedir` or `use_list_of_filenames`.

    lcformatdir : str or None
        If this is provided, gives the path to a directory when you've stored
        your lcformat description JSONs, other than the usual directories lcproc
        knows to search for them in. Use this along with `lcformat` to specify
        an LC format JSON file that's not currently registered with lcproc.

    Returns
    -------

    list of str
        A list of all star features pickles produced.


try:<EOL><INDENT>formatinfo = get_lcformat(lcformat,<EOL>use_lcformat_dir=lcformatdir)<EOL>if formatinfo:<EOL><INDENT>(dfileglob, readerfunc,<EOL>dtimecols, dmagcols, derrcols,<EOL>magsarefluxes, normfunc) = formatinfo<EOL><DEDENT>else:<EOL><INDENT>LOGERROR("<STR_LIT>")<EOL>return None<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION("<STR_LIT>")<EOL>return None<EOL><DEDENT>if not os.path.exists(outdir):<EOL><INDENT>os.makedirs(outdir)<EOL><DEDENT>if maxobjects:<EOL><INDENT>lclist = lclist[:maxobjects]<EOL><DEDENT>with open(lc_catalog_pickle, '<STR_LIT:rb>') as infd:<EOL><INDENT>kdt_dict = pickle.load(infd)<EOL><DEDENT>kdt = kdt_dict['<STR_LIT>']<EOL>objlist = kdt_dict['<STR_LIT>']['<STR_LIT>']<EOL>objlcfl = kdt_dict['<STR_LIT>']['<STR_LIT>']<EOL>tasks = [(x, outdir, kdt, objlist, objlcfl,<EOL>neighbor_radius_arcsec,<EOL>deredden, custom_bandpasses, lcformat) for x in lclist]<EOL>with ProcessPoolExecutor(max_workers=nworkers) as executor:<EOL><INDENT>resultfutures = executor.map(_starfeatures_worker, tasks)<EOL><DEDENT>results = [x for x in resultfutures]<EOL>resdict = {os.path.basename(x):y for (x,y) in zip(lclist, results)}<EOL>return resdict<EOL>

This runs `get_starfeatures` in parallel for all light curves in `lclist`.

    Parameters
    ----------

    lclist : list of str
        The list of light curve file names to process.

    outdir : str
        The output directory where the results will be placed.

    lc_catalog_pickle : str
        The path to a catalog containing at a dict with least:

        - an object ID array accessible with `dict['objects']['objectid']`

        - an LC filename array accessible with `dict['objects']['lcfname']`

        - a `scipy.spatial.KDTree` or `cKDTree` object to use for finding
          neighbors for each object accessible with `dict['kdtree']`

        A catalog pickle of the form needed can be produced using
        :py:func:`astrobase.lcproc.catalogs.make_lclist` or
        :py:func:`astrobase.lcproc.catalogs.filter_lclist`.

    neighbor_radius_arcsec : float
        This indicates the radius in arcsec to search for neighbors for this
        object using the light curve catalog's `kdtree`, `objlist`, `lcflist`,
        and in GAIA.

    maxobjects : int
        The number of objects to process from `lclist`.

    deredden : bool
        This controls if the colors and any color classifications will be
        dereddened using 2MASS DUST.

    custom_bandpasses : dict or None
        This is a dict used to define any custom bandpasses in the
        `in_objectinfo` dict you want to make this function aware of and
        generate colors for. Use the format below for this dict::

            {
            '<bandpass_key_1>':{'dustkey':'<twomass_dust_key_1>',
                                'label':'<band_label_1>'
                                'colors':[['<bandkey1>-<bandkey2>',
                                           '<BAND1> - <BAND2>'],
                                          ['<bandkey3>-<bandkey4>',
                                           '<BAND3> - <BAND4>']]},
            .
            ...
            .
            '<bandpass_key_N>':{'dustkey':'<twomass_dust_key_N>',
                                'label':'<band_label_N>'
                                'colors':[['<bandkey1>-<bandkey2>',
                                           '<BAND1> - <BAND2>'],
                                          ['<bandkey3>-<bandkey4>',
                                           '<BAND3> - <BAND4>']]},
            }

        Where:

        `bandpass_key` is a key to use to refer to this bandpass in the
        `objectinfo` dict, e.g. 'sdssg' for SDSS g band

        `twomass_dust_key` is the key to use in the 2MASS DUST result table for
        reddening per band-pass. For example, given the following DUST result
        table (using http://irsa.ipac.caltech.edu/applications/DUST/)::

            |Filter_name|LamEff |A_over_E_B_V_SandF|A_SandF|A_over_E_B_V_SFD|A_SFD|
            |char       |float  |float             |float  |float           |float|
            |           |microns|                  |mags   |                |mags |
             CTIO U       0.3734              4.107   0.209            4.968 0.253
             CTIO B       0.4309              3.641   0.186            4.325 0.221
             CTIO V       0.5517              2.682   0.137            3.240 0.165
            .
            .
            ...

        The `twomass_dust_key` for 'vmag' would be 'CTIO V'. If you want to
        skip DUST lookup and want to pass in a specific reddening magnitude
        for your bandpass, use a float for the value of
        `twomass_dust_key`. If you want to skip DUST lookup entirely for
        this bandpass, use None for the value of `twomass_dust_key`.

        `band_label` is the label to use for this bandpass, e.g. 'W1' for
        WISE-1 band, 'u' for SDSS u, etc.

        The 'colors' list contains color definitions for all colors you want
        to generate using this bandpass. this list contains elements of the
        form::

            ['<bandkey1>-<bandkey2>','<BAND1> - <BAND2>']

        where the the first item is the bandpass keys making up this color,
        and the second item is the label for this color to be used by the
        frontends. An example::

            ['sdssu-sdssg','u - g']

    lcformat : str
        This is the `formatkey` associated with your light curve format, which
        you previously passed in to the `lcproc.register_lcformat`
        function. This will be used to look up how to find and read the light
        curves specified in `basedir` or `use_list_of_filenames`.

    lcformatdir : str or None
        If this is provided, gives the path to a directory when you've stored
        your lcformat description JSONs, other than the usual directories lcproc
        knows to search for them in. Use this along with `lcformat` to specify
        an LC format JSON file that's not currently registered with lcproc.

    nworkers : int
        The number of parallel workers to launch.

    Returns
    -------

    dict
        A dict with key:val pairs of the input light curve filename and the
        output star features pickle for each LC processed.


try:<EOL><INDENT>formatinfo = get_lcformat(lcformat,<EOL>use_lcformat_dir=lcformatdir)<EOL>if formatinfo:<EOL><INDENT>(dfileglob, readerfunc,<EOL>dtimecols, dmagcols, derrcols,<EOL>magsarefluxes, normfunc) = formatinfo<EOL><DEDENT>else:<EOL><INDENT>LOGERROR("<STR_LIT>")<EOL>return None<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION("<STR_LIT>")<EOL>return None<EOL><DEDENT>if not fileglob:<EOL><INDENT>fileglob = dfileglob<EOL><DEDENT>LOGINFO('<STR_LIT>' % (lcformat, lcdir))<EOL>if recursive is False:<EOL><INDENT>matching = glob.glob(os.path.join(lcdir, fileglob))<EOL><DEDENT>else:<EOL><INDENT>if sys.version_info[:<NUM_LIT:2>] > (<NUM_LIT:3>,<NUM_LIT:4>):<EOL><INDENT>matching = glob.glob(os.path.join(lcdir,<EOL>'<STR_LIT>',<EOL>fileglob),recursive=True)<EOL><DEDENT>else:<EOL><INDENT>walker = os.walk(lcdir)<EOL>matching = []<EOL>for root, dirs, _files in walker:<EOL><INDENT>for sdir in dirs:<EOL><INDENT>searchpath = os.path.join(root,<EOL>sdir,<EOL>fileglob)<EOL>foundfiles = glob.glob(searchpath)<EOL>if foundfiles:<EOL><INDENT>matching.extend(foundfiles)<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>if matching and len(matching) > <NUM_LIT:0>:<EOL><INDENT>LOGINFO('<STR_LIT>' %<EOL>len(matching))<EOL>return parallel_starfeatures(matching,<EOL>outdir,<EOL>lc_catalog_pickle,<EOL>neighbor_radius_arcsec,<EOL>deredden=deredden,<EOL>custom_bandpasses=custom_bandpasses,<EOL>maxobjects=maxobjects,<EOL>lcformat=lcformat,<EOL>lcformatdir=lcformatdir,<EOL>nworkers=nworkers)<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>' % (lcformat,<EOL>lcdir))<EOL>return None<EOL><DEDENT>

This runs parallel star feature extraction for a directory of LCs.

    Parameters
    ----------

    lcdir : list of str
        The directory to search for light curves.

    outdir : str
        The output directory where the results will be placed.

    lc_catalog_pickle : str
        The path to a catalog containing at a dict with least:

        - an object ID array accessible with `dict['objects']['objectid']`

        - an LC filename array accessible with `dict['objects']['lcfname']`

        - a `scipy.spatial.KDTree` or `cKDTree` object to use for finding
          neighbors for each object accessible with `dict['kdtree']`

        A catalog pickle of the form needed can be produced using
        :py:func:`astrobase.lcproc.catalogs.make_lclist` or
        :py:func:`astrobase.lcproc.catalogs.filter_lclist`.

    neighbor_radius_arcsec : float
        This indicates the radius in arcsec to search for neighbors for this
        object using the light curve catalog's `kdtree`, `objlist`, `lcflist`,
        and in GAIA.

    fileglob : str
        The UNIX file glob to use to search for the light curves in `lcdir`. If
        None, the default value for the light curve format specified will be
        used.

    maxobjects : int
        The number of objects to process from `lclist`.

    deredden : bool
        This controls if the colors and any color classifications will be
        dereddened using 2MASS DUST.

    custom_bandpasses : dict or None
        This is a dict used to define any custom bandpasses in the
        `in_objectinfo` dict you want to make this function aware of and
        generate colors for. Use the format below for this dict::

            {
            '<bandpass_key_1>':{'dustkey':'<twomass_dust_key_1>',
                                'label':'<band_label_1>'
                                'colors':[['<bandkey1>-<bandkey2>',
                                           '<BAND1> - <BAND2>'],
                                          ['<bandkey3>-<bandkey4>',
                                           '<BAND3> - <BAND4>']]},
            .
            ...
            .
            '<bandpass_key_N>':{'dustkey':'<twomass_dust_key_N>',
                                'label':'<band_label_N>'
                                'colors':[['<bandkey1>-<bandkey2>',
                                           '<BAND1> - <BAND2>'],
                                          ['<bandkey3>-<bandkey4>',
                                           '<BAND3> - <BAND4>']]},
            }

        Where:

        `bandpass_key` is a key to use to refer to this bandpass in the
        `objectinfo` dict, e.g. 'sdssg' for SDSS g band

        `twomass_dust_key` is the key to use in the 2MASS DUST result table for
        reddening per band-pass. For example, given the following DUST result
        table (using http://irsa.ipac.caltech.edu/applications/DUST/)::

            |Filter_name|LamEff |A_over_E_B_V_SandF|A_SandF|A_over_E_B_V_SFD|A_SFD|
            |char       |float  |float             |float  |float           |float|
            |           |microns|                  |mags   |                |mags |
             CTIO U       0.3734              4.107   0.209            4.968 0.253
             CTIO B       0.4309              3.641   0.186            4.325 0.221
             CTIO V       0.5517              2.682   0.137            3.240 0.165
            .
            .
            ...

        The `twomass_dust_key` for 'vmag' would be 'CTIO V'. If you want to
        skip DUST lookup and want to pass in a specific reddening magnitude
        for your bandpass, use a float for the value of
        `twomass_dust_key`. If you want to skip DUST lookup entirely for
        this bandpass, use None for the value of `twomass_dust_key`.

        `band_label` is the label to use for this bandpass, e.g. 'W1' for
        WISE-1 band, 'u' for SDSS u, etc.

        The 'colors' list contains color definitions for all colors you want
        to generate using this bandpass. this list contains elements of the
        form::

            ['<bandkey1>-<bandkey2>','<BAND1> - <BAND2>']

        where the the first item is the bandpass keys making up this color,
        and the second item is the label for this color to be used by the
        frontends. An example::

            ['sdssu-sdssg','u - g']

    lcformat : str
        This is the `formatkey` associated with your light curve format, which
        you previously passed in to the `lcproc.register_lcformat`
        function. This will be used to look up how to find and read the light
        curves specified in `basedir` or `use_list_of_filenames`.

    lcformatdir : str or None
        If this is provided, gives the path to a directory when you've stored
        your lcformat description JSONs, other than the usual directories lcproc
        knows to search for them in. Use this along with `lcformat` to specify
        an LC format JSON file that's not currently registered with lcproc.

    nworkers : int
        The number of parallel workers to launch.

    Returns
    -------

    dict
        A dict with key:val pairs of the input light curve filename and the
        output star features pickle for each LC processed.


try:<EOL><INDENT>formatinfo = get_lcformat(lcformat,<EOL>use_lcformat_dir=lcformatdir)<EOL>if formatinfo:<EOL><INDENT>(fileglob, readerfunc,<EOL>dtimecols, dmagcols, derrcols,<EOL>magsarefluxes, normfunc) = formatinfo<EOL><DEDENT>else:<EOL><INDENT>LOGERROR("<STR_LIT>")<EOL>return None<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION("<STR_LIT>")<EOL>return None<EOL><DEDENT>if pfpickle.endswith('<STR_LIT>'):<EOL><INDENT>infd = gzip.open(pfpickle)<EOL><DEDENT>else:<EOL><INDENT>infd = open(pfpickle)<EOL><DEDENT>pf = pickle.load(infd)<EOL>infd.close()<EOL>lcfile = os.path.join(lcbasedir, pf['<STR_LIT>'])<EOL>objectid = pf['<STR_LIT>']<EOL>if '<STR_LIT>' in pf:<EOL><INDENT>kwargs = pf['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>kwargs = None<EOL><DEDENT>if kwargs and '<STR_LIT>' in kwargs and timecols is None:<EOL><INDENT>timecols = kwargs['<STR_LIT>']<EOL><DEDENT>elif not kwargs and not timecols:<EOL><INDENT>timecols = dtimecols<EOL><DEDENT>if kwargs and '<STR_LIT>' in kwargs and magcols is None:<EOL><INDENT>magcols = kwargs['<STR_LIT>']<EOL><DEDENT>elif not kwargs and not magcols:<EOL><INDENT>magcols = dmagcols<EOL><DEDENT>if kwargs and '<STR_LIT>' in kwargs and errcols is None:<EOL><INDENT>errcols = kwargs['<STR_LIT>']<EOL><DEDENT>elif not kwargs and not errcols:<EOL><INDENT>errcols = derrcols<EOL><DEDENT>if not os.path.exists(lcfile):<EOL><INDENT>LOGERROR("<STR_LIT>" % (lcfile, objectid))<EOL>return None<EOL><DEDENT>if starfeatures is not None and os.path.exists(starfeatures):<EOL><INDENT>with open(starfeatures,'<STR_LIT:rb>') as infd:<EOL><INDENT>starfeat = pickle.load(infd)<EOL><DEDENT>if starfeat['<STR_LIT>'].size > <NUM_LIT:0>:<EOL><INDENT>nbr_full_lcf = starfeat['<STR_LIT>'][<NUM_LIT:0>]<EOL>if os.path.exists(os.path.join(lcbasedir,<EOL>os.path.basename(nbr_full_lcf))):<EOL><INDENT>nbrlcf = os.path.join(lcbasedir,<EOL>os.path.basename(nbr_full_lcf))<EOL><DEDENT>elif os.path.exists(nbr_full_lcf):<EOL><INDENT>nbrlcf = nbr_full_lcf<EOL><DEDENT>else:<EOL><INDENT>LOGWARNING("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(os.path.basename(nbr_full_lcf),<EOL>os.path.dirname(nbr_full_lcf),<EOL>lcbasedir))<EOL>nbrlcf = None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>nbrlcf = None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>nbrlcf = None<EOL><DEDENT>try:<EOL><INDENT>lcdict = readerfunc(lcfile)<EOL>if ( (isinstance(lcdict, (list, tuple))) and<EOL>(isinstance(lcdict[<NUM_LIT:0>], dict)) ):<EOL><INDENT>lcdict = lcdict[<NUM_LIT:0>]<EOL><DEDENT>if nbrlcf is not None:<EOL><INDENT>nbrlcdict = readerfunc(nbrlcf)<EOL>if ( (isinstance(nbrlcdict, (list, tuple))) and<EOL>(isinstance(nbrlcdict[<NUM_LIT:0>], dict)) ):<EOL><INDENT>nbrlcdict = nbrlcdict[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>outfile = os.path.join(outdir, '<STR_LIT>' %<EOL>squeeze(objectid).replace('<STR_LIT:U+0020>','<STR_LIT:->'))<EOL>if normfunc is not None:<EOL><INDENT>lcdict = normfunc(lcdict)<EOL>if nbrlcf:<EOL><INDENT>nbrlcdict = normfunc(nbrlcdict)<EOL><DEDENT><DEDENT>resultdict = {}<EOL>for tcol, mcol, ecol in zip(timecols, magcols, errcols):<EOL><INDENT>if '<STR_LIT:.>' in tcol:<EOL><INDENT>tcolget = tcol.split('<STR_LIT:.>')<EOL><DEDENT>else:<EOL><INDENT>tcolget = [tcol]<EOL><DEDENT>times = _dict_get(lcdict, tcolget)<EOL>if nbrlcf:<EOL><INDENT>nbrtimes = _dict_get(nbrlcdict, tcolget)<EOL><DEDENT>else:<EOL><INDENT>nbrtimes = None<EOL><DEDENT>if '<STR_LIT:.>' in mcol:<EOL><INDENT>mcolget = mcol.split('<STR_LIT:.>')<EOL><DEDENT>else:<EOL><INDENT>mcolget = [mcol]<EOL><DEDENT>mags = _dict_get(lcdict, mcolget)<EOL>if nbrlcf:<EOL><INDENT>nbrmags = _dict_get(nbrlcdict, mcolget)<EOL><DEDENT>else:<EOL><INDENT>nbrmags = None<EOL><DEDENT>if '<STR_LIT:.>' in ecol:<EOL><INDENT>ecolget = ecol.split('<STR_LIT:.>')<EOL><DEDENT>else:<EOL><INDENT>ecolget = [ecol]<EOL><DEDENT>errs = _dict_get(lcdict, ecolget)<EOL>if nbrlcf:<EOL><INDENT>nbrerrs = _dict_get(nbrlcdict, ecolget)<EOL><DEDENT>else:<EOL><INDENT>nbrerrs = None<EOL><DEDENT>finind = np.isfinite(times) & np.isfinite(mags) & np.isfinite(errs)<EOL>ftimes, fmags, ferrs = times[finind], mags[finind], errs[finind]<EOL>if nbrlcf:<EOL><INDENT>nfinind = (np.isfinite(nbrtimes) &<EOL>np.isfinite(nbrmags) &<EOL>np.isfinite(nbrerrs))<EOL>nbrftimes, nbrfmags, nbrferrs = (nbrtimes[nfinind],<EOL>nbrmags[nfinind],<EOL>nbrerrs[nfinind])<EOL><DEDENT>nzind = np.nonzero(ferrs)<EOL>ftimes, fmags, ferrs = ftimes[nzind], fmags[nzind], ferrs[nzind]<EOL>if nbrlcf:<EOL><INDENT>nnzind = np.nonzero(nbrferrs)<EOL>nbrftimes, nbrfmags, nbrferrs = (nbrftimes[nnzind],<EOL>nbrfmags[nnzind],<EOL>nbrferrs[nnzind])<EOL><DEDENT>if normfunc is None:<EOL><INDENT>ntimes, nmags = normalize_magseries(<EOL>ftimes, fmags,<EOL>magsarefluxes=magsarefluxes<EOL>)<EOL>times, mags, errs = ntimes, nmags, ferrs<EOL>if nbrlcf:<EOL><INDENT>nbrntimes, nbrnmags = normalize_magseries(<EOL>nbrftimes, nbrfmags,<EOL>magsarefluxes=magsarefluxes<EOL>)<EOL>nbrtimes, nbrmags, nbrerrs = nbrntimes, nbrnmags, nbrferrs<EOL><DEDENT>else:<EOL><INDENT>nbrtimes, nbrmags, nbrerrs = None, None, None<EOL><DEDENT><DEDENT>else:<EOL><INDENT>times, mags, errs = ftimes, fmags, ferrs<EOL><DEDENT>if times.size > <NUM_LIT>:<EOL><INDENT>available_pfmethods = []<EOL>available_pgrams = []<EOL>available_bestperiods = []<EOL>for k in pf[mcol].keys():<EOL><INDENT>if k in PFMETHODS:<EOL><INDENT>available_pgrams.append(pf[mcol][k])<EOL>if k != '<STR_LIT>':<EOL><INDENT>available_pfmethods.append(<EOL>pf[mcol][k]['<STR_LIT>']<EOL>)<EOL>available_bestperiods.append(<EOL>pf[mcol][k]['<STR_LIT>']<EOL>)<EOL><DEDENT><DEDENT><DEDENT>featkey = '<STR_LIT>' % mcol<EOL>resultdict[featkey] = {}<EOL>pgramfeat = periodicfeatures.periodogram_features(<EOL>available_pgrams, times, mags, errs,<EOL>sigclip=sigclip,<EOL>pdiff_threshold=pdiff_threshold,<EOL>sidereal_threshold=sidereal_threshold,<EOL>sampling_peak_multiplier=sampling_peak_multiplier,<EOL>sampling_startp=sampling_startp,<EOL>sampling_endp=sampling_endp,<EOL>verbose=verbose<EOL>)<EOL>resultdict[featkey].update(pgramfeat)<EOL>resultdict[featkey]['<STR_LIT>'] = available_pfmethods<EOL>for _ind, pfm, bp in zip(range(len(available_bestperiods)),<EOL>available_pfmethods,<EOL>available_bestperiods):<EOL><INDENT>resultdict[featkey][pfm] = periodicfeatures.lcfit_features(<EOL>times, mags, errs, bp,<EOL>fourierorder=fourierorder,<EOL>transitparams=transitparams,<EOL>ebparams=ebparams,<EOL>sigclip=sigclip,<EOL>magsarefluxes=magsarefluxes,<EOL>verbose=verbose<EOL>)<EOL>phasedlcfeat = periodicfeatures.phasedlc_features(<EOL>times, mags, errs, bp,<EOL>nbrtimes=nbrtimes,<EOL>nbrmags=nbrmags,<EOL>nbrerrs=nbrerrs<EOL>)<EOL>resultdict[featkey][pfm].update(phasedlcfeat)<EOL><DEDENT><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>% (mcol, pfpickle))<EOL>featkey = '<STR_LIT>' % mcol<EOL>resultdict[featkey] = None<EOL><DEDENT><DEDENT>outfile = os.path.join(outdir, '<STR_LIT>' %<EOL>squeeze(objectid).replace('<STR_LIT:U+0020>','<STR_LIT:->'))<EOL>with open(outfile,'<STR_LIT:wb>') as outfd:<EOL><INDENT>pickle.dump(resultdict, outfd, pickle.HIGHEST_PROTOCOL)<EOL><DEDENT>return outfile<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>' %<EOL>(pfpickle, lcfile))<EOL>if raiseonfail:<EOL><INDENT>raise<EOL><DEDENT>else:<EOL><INDENT>return None<EOL><DEDENT><DEDENT>

This gets all periodic features for the object.

    Parameters
    ----------

    pfpickle : str
        The period-finding result pickle containing period-finder results to use
        for the calculation of LC fit, periodogram, and phased LC features.

    lcbasedir : str
        The base directory where the light curve for the current object is
        located.

    outdir : str
        The output directory where the results will be written.

    fourierorder : int
        The Fourier order to use to generate sinusoidal function and fit that to
        the phased light curve.

    transitparams : list of floats
        The transit depth, duration, and ingress duration to use to generate a
        trapezoid planet transit model fit to the phased light curve. The period
        used is the one provided in `period`, while the epoch is automatically
        obtained from a spline fit to the phased light curve.

    ebparams : list of floats
        The primary eclipse depth, eclipse duration, the primary-secondary depth
        ratio, and the phase of the secondary eclipse to use to generate an
        eclipsing binary model fit to the phased light curve. The period used is
        the one provided in `period`, while the epoch is automatically obtained
        from a spline fit to the phased light curve.

    pdiff_threshold : float
        This is the max difference between periods to consider them the same.

    sidereal_threshold : float
        This is the max difference between any of the 'best' periods and the
        sidereal day periods to consider them the same.

    sampling_peak_multiplier : float
        This is the minimum multiplicative factor of a 'best' period's
        normalized periodogram peak over the sampling periodogram peak at the
        same period required to accept the 'best' period as possibly real.

    sampling_startp, sampling_endp : float
        If the `pgramlist` doesn't have a time-sampling Lomb-Scargle
        periodogram, it will be obtained automatically. Use these kwargs to
        control the minimum and maximum period interval to be searched when
        generating this periodogram.

    starfeatures : str or None
        If not None, this should be the filename of the
        `starfeatures-<objectid>.pkl` created by
        :py:func:`astrobase.lcproc.lcsfeatures.get_starfeatures` for this
        object. This is used to get the neighbor's light curve and phase it with
        this object's period to see if this object is blended.

    timecols : list of str or None
        The timecol keys to use from the lcdict in calculating the features.

    magcols : list of str or None
        The magcol keys to use from the lcdict in calculating the features.

    errcols : list of str or None
        The errcol keys to use from the lcdict in calculating the features.

    lcformat : str
        This is the `formatkey` associated with your light curve format, which
        you previously passed in to the `lcproc.register_lcformat`
        function. This will be used to look up how to find and read the light
        curves specified in `basedir` or `use_list_of_filenames`.

    lcformatdir : str or None
        If this is provided, gives the path to a directory when you've stored
        your lcformat description JSONs, other than the usual directories lcproc
        knows to search for them in. Use this along with `lcformat` to specify
        an LC format JSON file that's not currently registered with lcproc.

    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 while working.

    raiseonfail : bool
        If True, will raise an Exception if something goes wrong.

    Returns
    -------

    str
        Returns a filename for the output pickle containing all of the periodic
        features for the input object's LC.


pfpickle, lcbasedir, outdir, starfeatures, kwargs = task<EOL>try:<EOL><INDENT>return get_periodicfeatures(pfpickle,<EOL>lcbasedir,<EOL>outdir,<EOL>starfeatures=starfeatures,<EOL>**kwargs)<EOL><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>' % pfpickle)<EOL><DEDENT>

This is a parallel worker for the drivers below.


try:<EOL><INDENT>formatinfo = get_lcformat(lcformat,<EOL>use_lcformat_dir=lcformatdir)<EOL>if formatinfo:<EOL><INDENT>(fileglob, readerfunc,<EOL>dtimecols, dmagcols, derrcols,<EOL>magsarefluxes, normfunc) = formatinfo<EOL><DEDENT>else:<EOL><INDENT>LOGERROR("<STR_LIT>")<EOL>return None<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION("<STR_LIT>")<EOL>return None<EOL><DEDENT>if not os.path.exists(outdir):<EOL><INDENT>os.makedirs(outdir)<EOL><DEDENT>if maxobjects:<EOL><INDENT>pfpkl_list = pfpkl_list[:maxobjects]<EOL><DEDENT>LOGINFO('<STR_LIT>' % len(pfpkl_list))<EOL>if starfeaturesdir and os.path.exists(starfeaturesdir):<EOL><INDENT>starfeatures_list = []<EOL>LOGINFO('<STR_LIT>')<EOL>for pfpkl in pfpkl_list:<EOL><INDENT>sfpkl1 = os.path.basename(pfpkl).replace('<STR_LIT>',<EOL>'<STR_LIT>')<EOL>sfpkl2 = sfpkl1.replace('<STR_LIT>','<STR_LIT>')<EOL>sfpath1 = os.path.join(starfeaturesdir, sfpkl1)<EOL>sfpath2 = os.path.join(starfeaturesdir, sfpkl2)<EOL>if os.path.exists(sfpath1):<EOL><INDENT>starfeatures_list.append(sfpkl1)<EOL><DEDENT>elif os.path.exists(sfpath2):<EOL><INDENT>starfeatures_list.append(sfpkl2)<EOL><DEDENT>else:<EOL><INDENT>starfeatures_list.append(None)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>starfeatures_list = [None for x in pfpkl_list]<EOL><DEDENT>kwargs = {'<STR_LIT>':fourierorder,<EOL>'<STR_LIT>':transitparams,<EOL>'<STR_LIT>':ebparams,<EOL>'<STR_LIT>':pdiff_threshold,<EOL>'<STR_LIT>':sidereal_threshold,<EOL>'<STR_LIT>':sampling_peak_multiplier,<EOL>'<STR_LIT>':sampling_startp,<EOL>'<STR_LIT>':sampling_endp,<EOL>'<STR_LIT>':timecols,<EOL>'<STR_LIT>':magcols,<EOL>'<STR_LIT>':errcols,<EOL>'<STR_LIT>':lcformat,<EOL>'<STR_LIT>':lcformatdir,<EOL>'<STR_LIT>':sigclip,<EOL>'<STR_LIT>':verbose}<EOL>tasks = [(x, lcbasedir, outdir, y, kwargs) for (x,y) in<EOL>zip(pfpkl_list, starfeatures_list)]<EOL>LOGINFO('<STR_LIT>')<EOL>for task in tqdm(tasks):<EOL><INDENT>_periodicfeatures_worker(task)<EOL><DEDENT>

This drives the periodicfeatures collection for a list of periodfinding
    pickles.

    Parameters
    ----------

    pfpkl_list : list of str
        The list of period-finding pickles to use.

    lcbasedir : str
        The base directory where the associated light curves are located.

    outdir : str
        The directory where the results will be written.

    starfeaturesdir : str or None
        The directory containing the `starfeatures-<objectid>.pkl` files for
        each object to use calculate neighbor proximity light curve features.

    fourierorder : int
        The Fourier order to use to generate sinusoidal function and fit that to
        the phased light curve.

    transitparams : list of floats
        The transit depth, duration, and ingress duration to use to generate a
        trapezoid planet transit model fit to the phased light curve. The period
        used is the one provided in `period`, while the epoch is automatically
        obtained from a spline fit to the phased light curve.

    ebparams : list of floats
        The primary eclipse depth, eclipse duration, the primary-secondary depth
        ratio, and the phase of the secondary eclipse to use to generate an
        eclipsing binary model fit to the phased light curve. The period used is
        the one provided in `period`, while the epoch is automatically obtained
        from a spline fit to the phased light curve.

    pdiff_threshold : float
        This is the max difference between periods to consider them the same.

    sidereal_threshold : float
        This is the max difference between any of the 'best' periods and the
        sidereal day periods to consider them the same.

    sampling_peak_multiplier : float
        This is the minimum multiplicative factor of a 'best' period's
        normalized periodogram peak over the sampling periodogram peak at the
        same period required to accept the 'best' period as possibly real.

    sampling_startp, sampling_endp : float
        If the `pgramlist` doesn't have a time-sampling Lomb-Scargle
        periodogram, it will be obtained automatically. Use these kwargs to
        control the minimum and maximum period interval to be searched when
        generating this periodogram.

    timecols : list of str or None
        The timecol keys to use from the lcdict in calculating the features.

    magcols : list of str or None
        The magcol keys to use from the lcdict in calculating the features.

    errcols : list of str or None
        The errcol keys to use from the lcdict in calculating the features.

    lcformat : str
        This is the `formatkey` associated with your light curve format, which
        you previously passed in to the `lcproc.register_lcformat`
        function. This will be used to look up how to find and read the light
        curves specified in `basedir` or `use_list_of_filenames`.

    lcformatdir : str or None
        If this is provided, gives the path to a directory when you've stored
        your lcformat description JSONs, other than the usual directories lcproc
        knows to search for them in. Use this along with `lcformat` to specify
        an LC format JSON file that's not currently registered with lcproc.

    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 while working.

    maxobjects : int
        The total number of objects to process from `pfpkl_list`.

    Returns
    -------

    Nothing.


<EOL>if not os.path.exists(outdir):<EOL><INDENT>os.makedirs(outdir)<EOL><DEDENT>if maxobjects:<EOL><INDENT>pfpkl_list = pfpkl_list[:maxobjects]<EOL><DEDENT>LOGINFO('<STR_LIT>' % len(pfpkl_list))<EOL>if starfeaturesdir and os.path.exists(starfeaturesdir):<EOL><INDENT>starfeatures_list = []<EOL>LOGINFO('<STR_LIT>')<EOL>for pfpkl in pfpkl_list:<EOL><INDENT>sfpkl1 = os.path.basename(pfpkl).replace('<STR_LIT>',<EOL>'<STR_LIT>')<EOL>sfpkl2 = sfpkl1.replace('<STR_LIT>','<STR_LIT>')<EOL>sfpath1 = os.path.join(starfeaturesdir, sfpkl1)<EOL>sfpath2 = os.path.join(starfeaturesdir, sfpkl2)<EOL>if os.path.exists(sfpath1):<EOL><INDENT>starfeatures_list.append(sfpkl1)<EOL><DEDENT>elif os.path.exists(sfpath2):<EOL><INDENT>starfeatures_list.append(sfpkl2)<EOL><DEDENT>else:<EOL><INDENT>starfeatures_list.append(None)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>starfeatures_list = [None for x in pfpkl_list]<EOL><DEDENT>kwargs = {'<STR_LIT>':fourierorder,<EOL>'<STR_LIT>':transitparams,<EOL>'<STR_LIT>':ebparams,<EOL>'<STR_LIT>':pdiff_threshold,<EOL>'<STR_LIT>':sidereal_threshold,<EOL>'<STR_LIT>':sampling_peak_multiplier,<EOL>'<STR_LIT>':sampling_startp,<EOL>'<STR_LIT>':sampling_endp,<EOL>'<STR_LIT>':timecols,<EOL>'<STR_LIT>':magcols,<EOL>'<STR_LIT>':errcols,<EOL>'<STR_LIT>':lcformat,<EOL>'<STR_LIT>':lcformat,<EOL>'<STR_LIT>':sigclip,<EOL>'<STR_LIT>':verbose}<EOL>tasks = [(x, lcbasedir, outdir, y, kwargs) for (x,y) in<EOL>zip(pfpkl_list, starfeatures_list)]<EOL>LOGINFO('<STR_LIT>')<EOL>with ProcessPoolExecutor(max_workers=nworkers) as executor:<EOL><INDENT>resultfutures = executor.map(_periodicfeatures_worker, tasks)<EOL><DEDENT>results = [x for x in resultfutures]<EOL>resdict = {os.path.basename(x):y for (x,y) in zip(pfpkl_list, results)}<EOL>return resdict<EOL>

This runs periodic feature generation in parallel for all periodfinding
    pickles in the input list.

    Parameters
    ----------

    pfpkl_list : list of str
        The list of period-finding pickles to use.

    lcbasedir : str
        The base directory where the associated light curves are located.

    outdir : str
        The directory where the results will be written.

    starfeaturesdir : str or None
        The directory containing the `starfeatures-<objectid>.pkl` files for
        each object to use calculate neighbor proximity light curve features.

    fourierorder : int
        The Fourier order to use to generate sinusoidal function and fit that to
        the phased light curve.

    transitparams : list of floats
        The transit depth, duration, and ingress duration to use to generate a
        trapezoid planet transit model fit to the phased light curve. The period
        used is the one provided in `period`, while the epoch is automatically
        obtained from a spline fit to the phased light curve.

    ebparams : list of floats
        The primary eclipse depth, eclipse duration, the primary-secondary depth
        ratio, and the phase of the secondary eclipse to use to generate an
        eclipsing binary model fit to the phased light curve. The period used is
        the one provided in `period`, while the epoch is automatically obtained
        from a spline fit to the phased light curve.

    pdiff_threshold : float
        This is the max difference between periods to consider them the same.

    sidereal_threshold : float
        This is the max difference between any of the 'best' periods and the
        sidereal day periods to consider them the same.

    sampling_peak_multiplier : float
        This is the minimum multiplicative factor of a 'best' period's
        normalized periodogram peak over the sampling periodogram peak at the
        same period required to accept the 'best' period as possibly real.

    sampling_startp, sampling_endp : float
        If the `pgramlist` doesn't have a time-sampling Lomb-Scargle
        periodogram, it will be obtained automatically. Use these kwargs to
        control the minimum and maximum period interval to be searched when
        generating this periodogram.

    timecols : list of str or None
        The timecol keys to use from the lcdict in calculating the features.

    magcols : list of str or None
        The magcol keys to use from the lcdict in calculating the features.

    errcols : list of str or None
        The errcol keys to use from the lcdict in calculating the features.

    lcformat : str
        This is the `formatkey` associated with your light curve format, which
        you previously passed in to the `lcproc.register_lcformat`
        function. This will be used to look up how to find and read the light
        curves specified in `basedir` or `use_list_of_filenames`.

    lcformatdir : str or None
        If this is provided, gives the path to a directory when you've stored
        your lcformat description JSONs, other than the usual directories lcproc
        knows to search for them in. Use this along with `lcformat` to specify
        an LC format JSON file that's not currently registered with lcproc.

    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 while working.

    maxobjects : int
        The total number of objects to process from `pfpkl_list`.

    nworkers : int
        The number of parallel workers to launch to process the input.

    Returns
    -------

    dict
        A dict containing key: val pairs of the input period-finder result and
        the output periodic feature result pickles for each input pickle is
        returned.


try:<EOL><INDENT>formatinfo = get_lcformat(lcformat,<EOL>use_lcformat_dir=lcformatdir)<EOL>if formatinfo:<EOL><INDENT>(dfileglob, readerfunc,<EOL>dtimecols, dmagcols, derrcols,<EOL>magsarefluxes, normfunc) = formatinfo<EOL><DEDENT>else:<EOL><INDENT>LOGERROR("<STR_LIT>")<EOL>return None<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION("<STR_LIT>")<EOL>return None<EOL><DEDENT>fileglob = pfpkl_glob<EOL>LOGINFO('<STR_LIT>' % pfpkl_dir)<EOL>if recursive is False:<EOL><INDENT>matching = glob.glob(os.path.join(pfpkl_dir, fileglob))<EOL><DEDENT>else:<EOL><INDENT>if sys.version_info[:<NUM_LIT:2>] > (<NUM_LIT:3>,<NUM_LIT:4>):<EOL><INDENT>matching = glob.glob(os.path.join(pfpkl_dir,<EOL>'<STR_LIT>',<EOL>fileglob),recursive=True)<EOL><DEDENT>else:<EOL><INDENT>walker = os.walk(pfpkl_dir)<EOL>matching = []<EOL>for root, dirs, _files in walker:<EOL><INDENT>for sdir in dirs:<EOL><INDENT>searchpath = os.path.join(root,<EOL>sdir,<EOL>fileglob)<EOL>foundfiles = glob.glob(searchpath)<EOL>if foundfiles:<EOL><INDENT>matching.extend(foundfiles)<EOL><DEDENT><DEDENT><DEDENT><DEDENT><DEDENT>if matching and len(matching) > <NUM_LIT:0>:<EOL><INDENT>LOGINFO('<STR_LIT>' %<EOL>len(matching))<EOL>return parallel_periodicfeatures(<EOL>matching,<EOL>lcbasedir,<EOL>outdir,<EOL>starfeaturesdir=starfeaturesdir,<EOL>fourierorder=fourierorder,<EOL>transitparams=transitparams,<EOL>ebparams=ebparams,<EOL>pdiff_threshold=pdiff_threshold,<EOL>sidereal_threshold=sidereal_threshold,<EOL>sampling_peak_multiplier=sampling_peak_multiplier,<EOL>sampling_startp=sampling_startp,<EOL>sampling_endp=sampling_endp,<EOL>timecols=timecols,<EOL>magcols=magcols,<EOL>errcols=errcols,<EOL>lcformat=lcformat,<EOL>lcformatdir=lcformatdir,<EOL>sigclip=sigclip,<EOL>verbose=verbose,<EOL>maxobjects=maxobjects,<EOL>nworkers=nworkers,<EOL>)<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>' % (pfpkl_dir))<EOL>return None<EOL><DEDENT>

This runs parallel periodicfeature extraction for a directory of
    periodfinding result pickles.

    Parameters
    ----------

    pfpkl_dir : str
        The directory containing the pickles to process.

    lcbasedir : str
        The directory where all of the associated light curve files are located.

    outdir : str
        The directory where all the output will be written.

    pfpkl_glob : str
        The UNIX file glob to use to search for period-finder result pickles in
        `pfpkl_dir`.

    starfeaturesdir : str or None
        The directory containing the `starfeatures-<objectid>.pkl` files for
        each object to use calculate neighbor proximity light curve features.

    fourierorder : int
        The Fourier order to use to generate sinusoidal function and fit that to
        the phased light curve.

    transitparams : list of floats
        The transit depth, duration, and ingress duration to use to generate a
        trapezoid planet transit model fit to the phased light curve. The period
        used is the one provided in `period`, while the epoch is automatically
        obtained from a spline fit to the phased light curve.

    ebparams : list of floats
        The primary eclipse depth, eclipse duration, the primary-secondary depth
        ratio, and the phase of the secondary eclipse to use to generate an
        eclipsing binary model fit to the phased light curve. The period used is
        the one provided in `period`, while the epoch is automatically obtained
        from a spline fit to the phased light curve.

    pdiff_threshold : float
        This is the max difference between periods to consider them the same.

    sidereal_threshold : float
        This is the max difference between any of the 'best' periods and the
        sidereal day periods to consider them the same.

    sampling_peak_multiplier : float
        This is the minimum multiplicative factor of a 'best' period's
        normalized periodogram peak over the sampling periodogram peak at the
        same period required to accept the 'best' period as possibly real.

    sampling_startp, sampling_endp : float
        If the `pgramlist` doesn't have a time-sampling Lomb-Scargle
        periodogram, it will be obtained automatically. Use these kwargs to
        control the minimum and maximum period interval to be searched when
        generating this periodogram.

    timecols : list of str or None
        The timecol keys to use from the lcdict in calculating the features.

    magcols : list of str or None
        The magcol keys to use from the lcdict in calculating the features.

    errcols : list of str or None
        The errcol keys to use from the lcdict in calculating the features.

    lcformat : str
        This is the `formatkey` associated with your light curve format, which
        you previously passed in to the `lcproc.register_lcformat`
        function. This will be used to look up how to find and read the light
        curves specified in `basedir` or `use_list_of_filenames`.

    lcformatdir : str or None
        If this is provided, gives the path to a directory when you've stored
        your lcformat description JSONs, other than the usual directories lcproc
        knows to search for them in. Use this along with `lcformat` to specify
        an LC format JSON file that's not currently registered with lcproc.

    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 while working.

    maxobjects : int
        The total number of objects to process from `pfpkl_list`.

    nworkers : int
        The number of parallel workers to launch to process the input.

    Returns
    -------

    dict
        A dict containing key: val pairs of the input period-finder result and
        the output periodic feature result pickles for each input pickle is
        returned.


try:<EOL><INDENT>formatinfo = get_lcformat(lcformat,<EOL>use_lcformat_dir=lcformatdir)<EOL>if formatinfo:<EOL><INDENT>(dfileglob, readerfunc,<EOL>dtimecols, dmagcols, derrcols,<EOL>magsarefluxes, normfunc) = formatinfo<EOL><DEDENT>else:<EOL><INDENT>LOGERROR("<STR_LIT>")<EOL>return None<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION("<STR_LIT>")<EOL>return None<EOL><DEDENT>lcdict = readerfunc(lcfile)<EOL>if ((isinstance(lcdict, (tuple, list))) and<EOL>isinstance(lcdict[<NUM_LIT:0>], dict)):<EOL><INDENT>lcdict = lcdict[<NUM_LIT:0>]<EOL><DEDENT>objectid = lcdict['<STR_LIT>']<EOL>times, mags, errs = lcdict[timecol], lcdict[magcol], lcdict[errcol]<EOL>if externalparams is not None:<EOL><INDENT>fsv = lcdict[externalparams['<STR_LIT>']]<EOL>fdv = lcdict[externalparams['<STR_LIT>']]<EOL>fkv = lcdict[externalparams['<STR_LIT>']]<EOL>xcc = lcdict[externalparams['<STR_LIT>']]<EOL>ycc = lcdict[externalparams['<STR_LIT>']]<EOL>bgv = lcdict[externalparams['<STR_LIT>']]<EOL>bge = lcdict[externalparams['<STR_LIT>']]<EOL>iha = lcdict[externalparams['<STR_LIT>']]<EOL>izd = lcdict[externalparams['<STR_LIT>']]<EOL><DEDENT>else:<EOL><INDENT>fsv = lcdict['<STR_LIT>']<EOL>fdv = lcdict['<STR_LIT>']<EOL>fkv = lcdict['<STR_LIT>']<EOL>xcc = lcdict['<STR_LIT>']<EOL>ycc = lcdict['<STR_LIT>']<EOL>bgv = lcdict['<STR_LIT>']<EOL>bge = lcdict['<STR_LIT>']<EOL>iha = lcdict['<STR_LIT>']<EOL>izd = lcdict['<STR_LIT>']<EOL><DEDENT>epd = epd_magseries(<EOL>times,<EOL>mags,<EOL>errs,<EOL>fsv, fdv, fkv, xcc, ycc, bgv, bge, iha, izd,<EOL>magsarefluxes=magsarefluxes,<EOL>epdsmooth_sigclip=epdsmooth_sigclip,<EOL>epdsmooth_windowsize=epdsmooth_windowsize,<EOL>epdsmooth_func=epdsmooth_func,<EOL>epdsmooth_extraparams=epdsmooth_extraparams<EOL>)<EOL>lcdict['<STR_LIT>'] = epd<EOL>outfile = os.path.join(<EOL>os.path.dirname(lcfile),<EOL>'<STR_LIT>' % (<EOL>squeeze(objectid).replace('<STR_LIT:U+0020>','<STR_LIT:->'),<EOL>magcol<EOL>)<EOL>)<EOL>with open(outfile,'<STR_LIT:wb>') as outfd:<EOL><INDENT>pickle.dump(lcdict, outfd,<EOL>protocol=pickle.HIGHEST_PROTOCOL)<EOL><DEDENT>return outfile<EOL>

This applies external parameter decorrelation (EPD) to a light curve.

    Parameters
    ----------

    lcfile : str
        The filename of the light curve file to process.

    timecol,magcol,errcol : str
        The keys in the lcdict produced by your light curve reader function that
        correspond to the times, mags/fluxes, and associated measurement errors
        that will be used as input to the EPD process.

    externalparams : dict or None
        This is a dict that indicates which keys in the lcdict obtained from the
        lcfile correspond to the required external parameters. As with timecol,
        magcol, and errcol, these can be simple keys (e.g. 'rjd') or compound
        keys ('magaperture1.mags'). The dict should look something like::

          {'fsv':'<lcdict key>' array: S values for each observation,
           'fdv':'<lcdict key>' array: D values for each observation,
           'fkv':'<lcdict key>' array: K values for each observation,
           'xcc':'<lcdict key>' array: x coords for each observation,
           'ycc':'<lcdict key>' array: y coords for each observation,
           'bgv':'<lcdict key>' array: sky background for each observation,
           'bge':'<lcdict key>' array: sky background err for each observation,
           'iha':'<lcdict key>' array: hour angle for each observation,
           'izd':'<lcdict key>' array: zenith distance for each observation}

        Alternatively, if these exact keys are already present in the lcdict,
        indicate this by setting externalparams to None.

    lcformat : str
        This is the `formatkey` associated with your light curve format, which
        you previously passed in to the `lcproc.register_lcformat`
        function. This will be used to look up how to find and read the light
        curves specified in `basedir` or `use_list_of_filenames`.

    lcformatdir : str or None
        If this is provided, gives the path to a directory when you've stored
        your lcformat description JSONs, other than the usual directories lcproc
        knows to search for them in. Use this along with `lcformat` to specify
        an LC format JSON file that's not currently registered with lcproc.

    epdsmooth_sigclip : float or int or sequence of two floats/ints or None
        This specifies how to sigma-clip the input LC before fitting the EPD
        function to it.

        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.

    epdsmooth_windowsize : int
        This is the number of LC points to smooth over to generate a smoothed
        light curve that will be used to fit the EPD function.

    epdsmooth_func : Python function
        This sets the smoothing filter function to use. A Savitsky-Golay filter
        is used to smooth the light curve by default. The functions that can be
        used with this kwarg are listed in `varbase.trends`. If you want to use
        your own function, it MUST have the following signature::

                def smoothfunc(mags_array, window_size, **extraparams)

        and return a numpy array of the same size as `mags_array` with the
        smoothed time-series. Any extra params can be provided using the
        `extraparams` dict.

    epdsmooth_extraparams : dict
        This is a dict of any extra filter params to supply to the smoothing
        function.

    Returns
    -------

    str
        Writes the output EPD light curve to a pickle that contains the lcdict
        with an added `lcdict['epd']` key, which contains the EPD times,
        mags/fluxes, and errs as `lcdict['epd']['times']`,
        `lcdict['epd']['mags']`, and `lcdict['epd']['errs']`. Returns the
        filename of this generated EPD LC pickle file.

    Notes
    -----

    - S -> measure of PSF sharpness (~1/sigma^2 sosmaller S = wider PSF)
    - D -> measure of PSF ellipticity in xy direction
    - K -> measure of PSF ellipticity in cross direction

    S, D, K are related to the PSF's variance and covariance, see eqn 30-33 in
    A. Pal's thesis: https://arxiv.org/abs/0906.3486


(lcfile, timecol, magcol, errcol,<EOL>externalparams, lcformat, lcformatdir, magsarefluxes,<EOL>epdsmooth_sigclip, epdsmooth_windowsize,<EOL>epdsmooth_func, epdsmooth_extraparams) = task<EOL>try:<EOL><INDENT>epd = apply_epd_magseries(lcfile,<EOL>timecol,<EOL>magcol,<EOL>errcol,<EOL>externalparams,<EOL>lcformat=lcformat,<EOL>lcformatdir=lcformatdir,<EOL>epdsmooth_sigclip=epdsmooth_sigclip,<EOL>epdsmooth_windowsize=epdsmooth_windowsize,<EOL>epdsmooth_func=epdsmooth_func,<EOL>epdsmooth_extraparams=epdsmooth_extraparams)<EOL>if epd is not None:<EOL><INDENT>LOGINFO('<STR_LIT>' % (lcfile, epd))<EOL>return epd<EOL><DEDENT>else:<EOL><INDENT>LOGERROR('<STR_LIT>' % lcfile)<EOL>return None<EOL><DEDENT><DEDENT>except Exception as e:<EOL><INDENT>LOGEXCEPTION('<STR_LIT>' % lcfile)<EOL>return None<EOL><DEDENT>

This is a parallel worker for the function below.

    Parameters
    ----------

    task : tuple
        - task[0] = lcfile
        - task[1] = timecol
        - task[2] = magcol
        - task[3] = errcol
        - task[4] = externalparams
        - task[5] = lcformat
        - task[6] = lcformatdir
        - task[7] = epdsmooth_sigclip
        - task[8] = epdsmooth_windowsize
        - task[9] = epdsmooth_func
        - task[10] = epdsmooth_extraparams

    Returns
    -------

    str or None
        If EPD succeeds for an input LC, returns the filename of the output EPD
        LC pickle file. If it fails, returns None.