Extract SeqRecords from the index by matching keys.

    keys - an iterable of sequence identifiers/accessions to select
    reffile - name of a FASTA file to extract the specified sequences from
    cache - save an index of the reference FASTA sequence offsets to disk?
    clean_accs - strip HMMer extensions from sequence accessions?

def intersect_keys(keys, reffile, cache=False, clean_accs=False):
    """Extract SeqRecords from the index by matching keys.

    keys - an iterable of sequence identifiers/accessions to select
    reffile - name of a FASTA file to extract the specified sequences from
    cache - save an index of the reference FASTA sequence offsets to disk?
    clean_accs - strip HMMer extensions from sequence accessions?
    """
    # Build/load the index of reference sequences
    index = None
    if cache:
        refcache = reffile + '.sqlite'
        if os.path.exists(refcache):
            if os.stat(refcache).st_mtime < os.stat(reffile).st_mtime:
                logging.warn("Outdated cache; rebuilding index")
            else:
                try:
                    index = (SeqIO.index_db(refcache,
                                            key_function=clean_accession)
                             if clean_accs
                             else SeqIO.index_db(refcache))

                except Exception:
                    logging.warn("Skipping corrupted cache; rebuilding index")
                    index = None
    else:
        refcache = ':memory:'
    if index is None:
        # Rebuild the index, for whatever reason
        index = (SeqIO.index_db(refcache, [reffile], 'fasta',
                                key_function=clean_accession)
                 if clean_accs
                 else SeqIO.index_db(refcache, [reffile], 'fasta'))

    # Extract records by key
    if clean_accs:
        keys = (clean_accession(k) for k in keys)
    for key in keys:
        try:
            record = index[key]
        except LookupError:
            # Missing keys are rare, so it's faster not to check every time
            logging.info("No match: %s", repr(key))
            continue
        yield record