MSG = 'A python package to run this executable is required,'
BIO = 'biopython'
BIO_BGZF = 'biopython with Bgzf support'
    NCBIXML = create_fake_class(MSG + BIO)
    NCBIWWW = create_fake_class(MSG + BIO)
def create_fake_class(msg):
        def __init__(self, *args, **kwargs):
def create_fake_funct(msg):
    def FakeRequiredfunct(*args, **kwargs):
    class FakePythonRequiredClass(object): class MalformedFile(Exception):
    'The input file is malformed'
    pass def error_quality_disagree(error_msg):
    'It checks if a Biopython ValueError is due to a malformed quality file'
    msg = 'Sequence length and number of quality scores disagree'
    msg2 = 'Lengths of sequence and quality values differs'
    if msg in str(error_msg) or msg2 in str(error_msg):
        return True
    else:
        return False class UnknownFormatError(Exception):
    'Raised when the format of a sequence file cannot be guessed'
    pass class IncompatibleFormatError(Exception):
    'Asked output format is incompatible with input file formats'
    pass class FileIsEmptyError(Exception):
    pass class IsSingleLineFastqError(Exception):
    'File format is single line'
    pass def group_in_packets(iterable, packet_size):
    'ABCDE -> (A, B), (C, D), (E,)'
    iterable = iter(iterable)
    while True:
        chunk = tuple(islice(iterable, packet_size))
        if not chunk:
            break
        yield chunk def group_in_packets_fill_last(iterable, packet_size, fillvalue=None):
    'ABCDE -> (A, B), (C, D), (E, None)'
    # It is faster than group_in_packets
    iterables = [iter(iterable)] * packet_size
    kwargs = {'fillvalue': fillvalue}
    return izip_longest(*iterables, **kwargs) def rel_symlink(path1, path2):
    'It makes the relative to path1 from within dirname(path2)'
    # The working directory can not be used because it is not thread safe
    # working directory is a global environment variable shared by all threads
    path1 = os.path.abspath(path1)
    path2 = os.path.abspath(path2)
    rel_path1 = _rel_path(path1, path2)

    fname2 = os.path.split(path2)[-1]

    temp_dir = tempfile.mkdtemp()
    try:
        temp_link_path = os.path.join(temp_dir, fname2)

        os.symlink(rel_path1, temp_link_path)
        shutil.move(temp_link_path, path2)
    finally:
        os.rmdir(temp_dir) def flush_fhand(fhand):
    try:
        fhand.flush()
    except IOError, error:
        # The pipe could be already closed
        if 'Broken pipe' not in str(error):
            raise FILETYPE = 'file'
STRINGIOTYPE = 'stringio'
OTHERTYPE = 'othertype'
FILEFORMAT_INVENTORY = {}
def _get_some_qual_and_lengths(fhand, force_file_as_non_seek):
def _guess_fastq_version(fhand, force_file_as_non_seek):
def _get_instance_type(fhand):
def _get_fhand_id(fhand):
def get_format(fhand):
def set_format(fhand, file_format):
def _guess_format(fhand, force_file_as_non_seek): GUESS_FORMAT = 'guess' SEQS_PASSED = 'seqs_passed' SEQS_FILTERED_OUT = 'seqs_filtered_out' SEQITEM = 'seqitem' SEQRECORD = 'seqrecord' ORPHAN_SEQS = 'orphan_seqs' SANGER_FASTQ_FORMATS = ('fastq-sanger', 'fastq') ILLUMINA_FASTQ_FORMATS = ('fastq-illumina',) def get_setting(key):
    'It returns the value for one setting'
    return _settings[key] class SeqItem(_SeqItem):
    def __new__(cls, name, lines, annotations=None):
        # This subclass is required to have a default value in a namedtuple
        if annotations is None:
            annotations = {}
        # add default values
        return super(SeqItem, cls).__new__(cls, name, lines, annotations) def get_str_seq(seq):
    seq_class = seq.kind
    if seq_class == SEQITEM:
        seq = seq.object.lines[1].strip()
    elif seq_class == SEQRECORD:
        seq = str(seq.object.seq)
    return seq.strip() def assing_kind_to_seqs(kind, seqs, file_format):
    'It puts each seq into a NamedTuple named Seq'
    return (SeqWrapper(kind, seq, file_format) for seq in seqs)
from itertools import chain, tee, ifilter
from shutil import copyfileobj
from tempfile import NamedTemporaryFile
from crumbs.utils.optional_modules import (FastaIterator, QualPhredIterator,
                                           PairedFastaQualIterator,
                                           FastqPhredIterator, write_seqrecs,
                                           FastqSolexaIterator,
                                           FastqIlluminaIterator,
                                           parse_into_seqrecs)
from crumbs.seq.utils.data import (ambiguous_rna_letters,
                                   ambiguous_dna_letters,
                                   extended_protein_letters)
from crumbs.exceptions import (MalformedFile, error_quality_disagree,
                               UnknownFormatError, IncompatibleFormatError,
                               FileIsEmptyError, IsSingleLineFastqError)
from crumbs.iterutils import group_in_packets, group_in_packets_fill_last
from crumbs.utils.file_utils import rel_symlink, flush_fhand
from crumbs.seq.utils.file_formats import get_format, peek_chunk_from_file
from crumbs.utils.tags import (GUESS_FORMAT, SEQS_PASSED, SEQS_FILTERED_OUT,
                               SEQITEM, SEQRECORD, ORPHAN_SEQS,
                               SANGER_FASTQ_FORMATS, ILLUMINA_FASTQ_FORMATS)
from crumbs.settings import get_setting
from crumbs.seq.seq import SeqItem, get_str_seq, assing_kind_to_seqs
import cStringIO





# pylint: disable=C0111


def _clean_seqrecord_stream(seqs):
    'It removes the empty seqs and fixes the descriptions.'
    for seq in seqs:
        if seq and str(seq.seq):
            if seq.description == '<unknown description>':
                seq.description = ''
            yield seq


def _write_seqrecords(seqs, fhand=None, file_format='fastq'):
    'It writes a stream of sequences to a file'
    if fhand is None:
        fhand = NamedTemporaryFile(suffix='.' + file_format.replace('-', '_'))
    seqs = _clean_seqrecord_stream(seqs)
    try:
        write_seqrecs(seqs, fhand, file_format)
    except IOError, error:
        # The pipe could be already closed
        if not 'Broken pipe' in str(error):
            raise
    return fhand


def _write_seqrecord_packets(fhand, seq_packets, file_format='fastq',
                            workers=None):
    'It writes to file a stream of SeqRecord lists'
    try:
        _write_seqrecords(chain.from_iterable(seq_packets), fhand,
                         file_format=file_format)
    except BaseException:
        if workers is not None:
            workers.terminate()
        raise


def write_seq_packets(fhand, seq_packets, file_format='fastq', workers=None):
    'It writes to file a stream of seq lists'
    try:
        write_seqs(chain.from_iterable(seq_packets), fhand,
                   file_format=file_format)
    except BaseException:
        if workers is not None:
            workers.terminate()
        raise


def _write_filter_trim_packets(passed_fhand, diverted_fhand, packets,
                               file_format='fastq', workers=None,
                               seqs_diverted=SEQS_FILTERED_OUT):
    'It writes the filter stream into passed and filtered out sequence files'

    if diverted_fhand is None:
        seq_packets = (p[SEQS_PASSED] for p in packets)
        seqs = (s for pair in chain.from_iterable(seq_packets) for s in pair)
        try:
            return write_seqs(seqs, passed_fhand, file_format=file_format)
        except BaseException:
            if workers is not None:
                workers.terminate()
            raise

    flatten_pairs = lambda pairs: (seq for pair in pairs for seq in pair)
    for packet in packets:
        try:
            write_seqs(flatten_pairs(packet[SEQS_PASSED]), fhand=passed_fhand,
                       file_format=file_format)
            # if diverted seqs are filtered aout they are a list of list
            # as not diverted seqs.
            # if they are orphan, they are a list of seqs
            if seqs_diverted == SEQS_FILTERED_OUT:
                seqs = flatten_pairs(packet[seqs_diverted])
            else:
                seqs = packet[seqs_diverted]
            write_seqs(seqs, fhand=diverted_fhand, file_format=file_format)

        except BaseException:
            if workers is not None:
                workers.terminate()
            raise


def write_filter_packets(passed_fhand, filtered_fhand, filter_packets,
                         file_format='fastq', workers=None):
    'It writes the filter stream into passed and filtered out sequence files'
    _write_filter_trim_packets(passed_fhand, filtered_fhand, filter_packets,
                               file_format=file_format, workers=workers,
                               seqs_diverted=SEQS_FILTERED_OUT)


def write_trim_packets(passed_fhand, orphan_fhand, trim_packets,
                       file_format='fastq', workers=None):
    'It writes the filter stream into passed and filtered out sequence files'
    _write_filter_trim_packets(passed_fhand, orphan_fhand, trim_packets,
                               file_format=file_format, workers=workers,
                               seqs_diverted=ORPHAN_SEQS)


def title2ids(title):
    '''It returns the id, name and description as a tuple.

    It takes the title of the FASTA file (without the beginning >)
    '''
    items = title.strip().split()
    name = items[0]
    id_ = name
    if len(items) > 1:
        desc = ' '.join(items[1:])
    else:
        desc = ''
    return id_, name, desc



def read_seq_packets(fhands, size=get_setting('PACKET_SIZE'), out_format=None,