def color_classification(colorfeatures, pmfeatures):
possible_classes = []<EOL>if not colorfeatures:<EOL><INDENT>return possible_classes<EOL><DEDENT>if not pmfeatures:<EOL><INDENT>return possible_classes<EOL><DEDENT>if ( ('<STR_LIT>' in colorfeatures) and<EOL>(colorfeatures['<STR_LIT>'] is not None) and<EOL>(np.isfinite(colorfeatures['<STR_LIT>'])) ):<EOL><INDENT>u = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>u = np.nan<EOL><DEDENT>if ( ('<STR_LIT>' in colorfeatures) and<EOL>(colorfeatures['<STR_LIT>'] is not None) and<EOL>(np.isfinite(colorfeatures['<STR_LIT>'])) ):<EOL><INDENT>g = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>g = np.nan<EOL><DEDENT>if ( ('<STR_LIT>' in colorfeatures) and<EOL>(colorfeatures['<STR_LIT>'] is not None) and<EOL>(np.isfinite(colorfeatures['<STR_LIT>'])) ):<EOL><INDENT>r = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>r = np.nan<EOL><DEDENT>if ( ('<STR_LIT>' in colorfeatures) and<EOL>(colorfeatures['<STR_LIT>'] is not None) and<EOL>(np.isfinite(colorfeatures['<STR_LIT>'])) ):<EOL><INDENT>i = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>i = np.nan<EOL><DEDENT>if ( ('<STR_LIT>' in colorfeatures) and<EOL>(colorfeatures['<STR_LIT>'] is not None) and<EOL>(np.isfinite(colorfeatures['<STR_LIT>'])) ):<EOL><INDENT>z = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>z = np.nan<EOL><DEDENT>if ( ('<STR_LIT>' in colorfeatures) and<EOL>(colorfeatures['<STR_LIT>'] is not None) and<EOL>(np.isfinite(colorfeatures['<STR_LIT>'])) ):<EOL><INDENT>j = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>j = np.nan<EOL><DEDENT>if ( ('<STR_LIT>' in colorfeatures) and<EOL>(colorfeatures['<STR_LIT>'] is not None) and<EOL>(np.isfinite(colorfeatures['<STR_LIT>'])) ):<EOL><INDENT>h = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>h = np.nan<EOL><DEDENT>if ( ('<STR_LIT>' in colorfeatures) and<EOL>(colorfeatures['<STR_LIT>'] is not None) and<EOL>(np.isfinite(colorfeatures['<STR_LIT>'])) ):<EOL><INDENT>k = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>k = np.nan<EOL><DEDENT>if '<STR_LIT>' in colorfeatures and colorfeatures['<STR_LIT>'] is not None:<EOL><INDENT>um = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>um = np.nan<EOL><DEDENT>if '<STR_LIT>' in colorfeatures and colorfeatures['<STR_LIT>'] is not None:<EOL><INDENT>gm = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>gm = np.nan<EOL><DEDENT>if '<STR_LIT>' in colorfeatures and colorfeatures['<STR_LIT>'] is not None:<EOL><INDENT>rm = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>rm = np.nan<EOL><DEDENT>if '<STR_LIT>' in colorfeatures and colorfeatures['<STR_LIT>'] is not None:<EOL><INDENT>im = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>im = np.nan<EOL><DEDENT>if '<STR_LIT>' in colorfeatures and colorfeatures['<STR_LIT>'] is not None:<EOL><INDENT>zm = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>zm = np.nan<EOL><DEDENT>if '<STR_LIT>' in colorfeatures and colorfeatures['<STR_LIT>'] is not None:<EOL><INDENT>jm = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>jm = np.nan<EOL><DEDENT>if '<STR_LIT>' in colorfeatures and colorfeatures['<STR_LIT>'] is not None:<EOL><INDENT>hm = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>hm = np.nan<EOL><DEDENT>if '<STR_LIT>' in colorfeatures and colorfeatures['<STR_LIT>'] is not None:<EOL><INDENT>km = colorfeatures['<STR_LIT>']<EOL><DEDENT>else:<EOL><INDENT>km = np.nan<EOL><DEDENT>rpmj = pmfeatures['<STR_LIT>'] if np.isfinite(pmfeatures['<STR_LIT>']) else None<EOL>if (np.isfinite(u) and np.isfinite(g) and<EOL>np.isfinite(r) and np.isfinite(i) and<EOL>np.isfinite(z)):<EOL><INDENT>v_color = <NUM_LIT>*(u-g)-<NUM_LIT>*(g-r)+<NUM_LIT>*(r-i)+<NUM_LIT>*(i-z)<EOL><DEDENT>else:<EOL><INDENT>v_color = np.nan<EOL><DEDENT>if (np.isfinite(u) and np.isfinite(g) and np.isfinite(r)):<EOL><INDENT>p1_color = <NUM_LIT>*(u-g)+<NUM_LIT>*(g-r)-<NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>p1_color = np.nan<EOL><DEDENT>if (np.isfinite(u) and np.isfinite(g) and<EOL>np.isfinite(r) and np.isfinite(i)):<EOL><INDENT>l_color = -<NUM_LIT>*u + <NUM_LIT>*g - <NUM_LIT>*r - <NUM_LIT>*i + <NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>l_color = np.nan<EOL><DEDENT>if (np.isfinite(u) and np.isfinite(g) and np.isfinite(r)):<EOL><INDENT>s_color = -<NUM_LIT>*u + <NUM_LIT>*g - <NUM_LIT>*r + <NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>s_color = np.nan<EOL><DEDENT>if (np.isfinite(u) and np.isfinite(g) and np.isfinite(r)):<EOL><INDENT>d_ug = (u-g) + <NUM_LIT>*(g-r) - <NUM_LIT><EOL>d_gr = <NUM_LIT>*(u-g) - (g-r) - <NUM_LIT><EOL><DEDENT>else:<EOL><INDENT>d_ug, d_gr = np.nan, np.nan<EOL><DEDENT>m_subtype, m_sti, m_sts = mdwarf_subtype_from_sdsscolor(r-i, i-z)<EOL>if m_subtype and rpmj and rpmj > <NUM_LIT:1.0>:<EOL><INDENT>possible_classes.append('<STR_LIT:d>' + m_subtype)<EOL><DEDENT>if ( np.isfinite(u) and np.isfinite(g) and np.isfinite(r) and<EOL>((g-r) < -<NUM_LIT>) and ((g-r) > -<NUM_LIT:1.0>) and<EOL>((u-g) < <NUM_LIT>) and ((u-g) > -<NUM_LIT:1>) and<EOL>((u-g+<NUM_LIT:2>*(g-r)) < -<NUM_LIT:0.1>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( np.isfinite(u) and np.isfinite(g) and np.isfinite(r) and<EOL>((u-g) < <NUM_LIT>) and ((u-g) > <NUM_LIT>) and<EOL>((g-r) < <NUM_LIT>) and ((g-r) > -<NUM_LIT:0.5>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(p1_color) and np.isfinite(p1_color) and<EOL>np.isfinite(u) and np.isfinite(g) and np.isfinite(r) ) and<EOL>(p1_color < -<NUM_LIT>) and (p1_color > -<NUM_LIT>) and<EOL>((u-g) < <NUM_LIT>) and ((u-g) > <NUM_LIT>) and<EOL>((g-r) < <NUM_LIT>) and ((g-r) > <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(u) and np.isfinite(g) and np.isfinite(r) and<EOL>np.isfinite(l_color)) and<EOL>((g-r) < <NUM_LIT>) and ((g-r) > -<NUM_LIT:0.5>) and<EOL>((u-g) < <NUM_LIT>) and ((u-g) > <NUM_LIT>) and<EOL>(l_color > <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(p1_color) and np.isfinite(s_color)) and<EOL>(-<NUM_LIT:0.1> < p1_color < <NUM_LIT>) and (s_color > <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(g) and np.isfinite(g) and np.isfinite(r)) and<EOL>((g-r) < <NUM_LIT>) and ((g-r) > <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(g) and np.isfinite(r)) and<EOL>((g-r) < <NUM_LIT>) and ((g-r) > <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(u) and np.isfinite(g) and<EOL>np.isfinite(r) and np.isfinite(i) and<EOL>np.isfinite(l_color)) and<EOL>((g-r) > <NUM_LIT>) and ((g-r) < <NUM_LIT>) and<EOL>(l_color > <NUM_LIT>) and ((u-g) > <NUM_LIT>) and ((u-g) < <NUM_LIT>) and<EOL>((r-i) > <NUM_LIT>) and ((r-i) < <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(u) and np.isfinite(g) and<EOL>np.isfinite(r) and np.isfinite(s_color)) and<EOL>((u-g) < <NUM_LIT>) and ((u-g) > <NUM_LIT>) and<EOL>((g-r) < <NUM_LIT>) and ((g-r) > <NUM_LIT>) and<EOL>(s_color < -<NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(g) and np.isfinite(r)) and<EOL>((g-r) < <NUM_LIT>) and ((g-r) > <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(g) and np.isfinite(r) and np.isfinite(i)) and<EOL>((g-r) > <NUM_LIT>) and ((r-i) < <NUM_LIT>) and ((r-i) > <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(j) and np.isfinite(h) and np.isfinite(k) and<EOL>np.isfinite(g) and np.isfinite(i)) and<EOL>((j-k) > <NUM_LIT>) and<EOL>((j-h) < (<NUM_LIT>*(j-k) + <NUM_LIT>)) and<EOL>((j-h) > (<NUM_LIT>*(j-k) + <NUM_LIT>)) and<EOL>((g-i) > (<NUM_LIT>*(i-k) - <NUM_LIT>)) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(um) and np.isfinite(gm) and<EOL>np.isfinite(rm) and np.isfinite(im)) and<EOL>((um-gm) < <NUM_LIT>) and ((gm-rm) > -<NUM_LIT>) and<EOL>((gm-rm) < <NUM_LIT>) and ((rm-im) > <NUM_LIT:0.5>) and<EOL>((rm-im) < <NUM_LIT>) and<EOL>((gm-rm) > (-<NUM_LIT>*(rm-im)+<NUM_LIT>)) and<EOL>((gm-rm) < (<NUM_LIT>*(rm-im)+<NUM_LIT:0.5>)) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(um) and np.isfinite(gm) and np.isfinite(rm) and<EOL>np.isfinite(im) and np.isfinite(zm)) and<EOL>(zm < <NUM_LIT>) and (um > <NUM_LIT>) and (gm > <NUM_LIT>) and<EOL>(rm > <NUM_LIT>) and ((im - zm) > <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(u) and np.isfinite(g) and np.isfinite(r) and<EOL>np.isfinite(i) and np.isfinite(z) and np.isfinite(d_ug) and<EOL>np.isfinite(d_gr)) and<EOL>((u-g) > <NUM_LIT>) and ((u-g) < <NUM_LIT>) and<EOL>(d_ug > -<NUM_LIT>) and (d_ug < <NUM_LIT>) and<EOL>(d_gr > <NUM_LIT>) and (d_gr < <NUM_LIT>) and<EOL>((r-i) > -<NUM_LIT>) and ((r-i) < <NUM_LIT>) and<EOL>((i-z) > -<NUM_LIT>) and ((i-z) < <NUM_LIT>) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>if ( (np.isfinite(u) and np.isfinite(g) and np.isfinite(r)) and<EOL>( (((u-g) > -<NUM_LIT:0.1>) and ((u-g) < <NUM_LIT>) and<EOL>((g-r) > -<NUM_LIT>) and ((g-r) < <NUM_LIT:0.5>)) or<EOL>((u-g) > (<NUM_LIT>*(g-r) + <NUM_LIT>)) ) ):<EOL><INDENT>possible_classes.append('<STR_LIT>')<EOL><DEDENT>return {'<STR_LIT>':possible_classes,<EOL>'<STR_LIT>':v_color,<EOL>'<STR_LIT>':p1_color,<EOL>'<STR_LIT>':s_color,<EOL>'<STR_LIT>':l_color,<EOL>'<STR_LIT>':d_ug,<EOL>'<STR_LIT>':d_gr,<EOL>'<STR_LIT>':m_sti,<EOL>'<STR_LIT>':m_sts}<EOL>
This calculates rough star type classifications based on star colors
    in the ugrizJHK bands.

    Uses the output from `color_features` and `coord_features`. By default,
    `color_features` will use dereddened colors, as are expected by most
    relations here.

    Based on the color cuts from:

    - SDSS SEGUE (Yanny+ 2009)
    - SDSS QSO catalog (Schneider+ 2007)
    - SDSS RR Lyrae catalog (Sesar+ 2011)
    - SDSS M-dwarf catalog (West+ 2008)
    - Helmi+ 2003
    - Bochanski+ 2014

    Parameters
    ----------

    colorfeatures : dict
        This is the dict produced by the `color_features` function.

    pmfeatures : dict
        This is the dict produced by the `coord_features` function.

    Returns
    -------

    dict
        A dict containing all of the possible classes this object can belong to
        as a list in the `color_classes` key, and values of the various color
        indices used to arrive to that conclusion as the other keys.