def clusters_from_uc_file(uc_lines,
                          error_on_multiple_hits=True):
    """ Given an open .uc file, return lists (clusters, failures, new_seeds)

        uc_lines: open .uc file, or similar object -- this is the output
         generated by uclust's -uc parameter
        error_on_multiple_hits: if True (default), when a single query hits
         to multiple seeds, as can happen when --allhits is passed to uclust,
         throw a UclustParseError. if False, when a single query hits to
         multiple seeds, it will appear in each cluster.

        This function processes all hit (H), seed (S), and no hit (N) lines
         to return all clusters, failures, and new_seeds generated in
         a uclust run. failures should only arise when users have passed
         --lib and --libonly, and a sequence doesn't cluster to any existing
         reference database sequences.

    """
    clusters = {}
    failures = []
    seeds = []
    all_hits = set()
    # the types of hit lines we're interested in here
    # are hit (H), seed (S), library seed (L) and no hit (N)
    hit_types = {}.fromkeys(list('HSNL'))
    for record in get_next_record_type(uc_lines, hit_types):
        hit_type = record[0]
        # sequence identifiers from the fasta header lines only
        # (no comment data) are stored to identify a sequence in
        # a cluster -- strip off any comments here as this value
        # is used in several places
        query_id = record[8].split()[0]
        target_cluster = record[9].split()[0]
        if hit_type == 'H':
            if error_on_multiple_hits and query_id in all_hits:
                raise UclustParseError("Query id " + query_id + " hit multiple seeds. "
                                       "This can happen if --allhits is "
                                       "enabled in the call to uclust, which isn't supported by default. "
                                       "Call clusters_from_uc_file(lines, error_on_multiple_hits=False) to "
                                       "allow a query to cluster to multiple seeds.")
            else:
                # add the hit to its existing cluster (either library
                # or new cluster)
                clusters[target_cluster].append(query_id)
                all_hits.add(query_id)
        elif hit_type == 'S':
            # a new seed was identified -- create a cluster with this
            # sequence as the first instance
            if query_id in clusters:
                raise UclustParseError("A seq id was provided as a seed, but that seq id already "
                                       "represents a cluster. Are there overlapping seq ids in your "
                                       "reference and input files or repeated seq ids in either? "
                                       "Offending seq id is %s" % query_id)
            clusters[query_id] = [query_id]
            seeds.append(query_id)
        elif hit_type == 'L':
            # a library seed was identified -- create a cluster with this
            # id as the index, but don't give it any instances yet bc the hit
            # line will be specified separately. note we need to handle these
            # lines separately from the H lines to detect overlapping seq ids
            # between the reference and the input fasta files
            if query_id in clusters:
                raise UclustParseError("A seq id was provided as a seed, but that seq id already "
                                       "represents a cluster. Are there overlapping seq ids in your "
                                       "reference and input files or repeated seq ids in either? "
                                       "Offending seq id is %s" % query_id)
            clusters[query_id] = []
        elif hit_type == 'N':
            # a failure was identified -- add it to the failures list
            failures.append(query_id)
        else:
            # shouldn't be possible to get here, but provided for
            # clarity
            raise UclustParseError(
                "Unexpected result parsing line:\n%s" %
                '\t'.join(record))

    # will need to return the full clusters dict, I think, to support
    # useful identifiers in reference database clustering
    # return  clusters.values(), failures, seeds
    return clusters, failures, seeds
Given an open .uc file, return lists (clusters, failures, new_seeds)

        uc_lines: open .uc file, or similar object -- this is the output
         generated by uclust's -uc parameter
        error_on_multiple_hits: if True (default), when a single query hits
         to multiple seeds, as can happen when --allhits is passed to uclust,
         throw a UclustParseError. if False, when a single query hits to
         multiple seeds, it will appear in each cluster.

        This function processes all hit (H), seed (S), and no hit (N) lines
         to return all clusters, failures, and new_seeds generated in
         a uclust run. failures should only arise when users have passed
         --lib and --libonly, and a sequence doesn't cluster to any existing
         reference database sequences.