# Path: crumbs/seq/seq.py
# class SeqItem(_SeqItem):
#     def __new__(cls, name, lines, annotations=None):
# def get_title(seq):
# def get_description(seq):
# def get_name(seq):
# def get_file_format(seq):
# def _break():
# def _is_fastq_plus_line(line, seq_name):
# def _get_seqitem_quals(seq):
# def get_str_seq(seq):
# def get_length(seq):
# def _get_seqitem_qualities(seqwrap):
# def get_int_qualities(seq):
# def _int_quals_to_str_quals(int_quals, out_format):
# def get_str_qualities(seq, out_format=None):
# def get_annotations(seq):
# def _copy_seqrecord(seqrec, seq=None, name=None, id_=None):
# def _copy_seqitem(seqwrapper, seq=None, name=None):
# def copy_seq(seqwrapper, seq=None, name=None):
# def _slice_seqitem(seqwrap, start, stop):
# def slice_seq(seq, start=None, stop=None):
# def assing_kind_to_seqs(kind, seqs, file_format):
# SANGER_QUALS = {chr(i): i - 33 for i in range(33, 127)}
# ILLUMINA_QUALS = {chr(i): i - 64 for i in range(64, 127)}
# SANGER_STRS = {i - 33: chr(i)  for i in range(33, 127)}
# ILLUMINA_STRS = {i - 64: chr(i) for i in range(64, 127)}
# 
# Path: crumbs/utils/tags.py
# SEQITEM = 'seqitem'
# 
# Path: crumbs/seq/bulk_filters.py
# def filter_duplicates(in_fhands, out_fhand, paired_reads, use_length=None,
#                       n_seqs_packet=None, tempdir=None):
#     if not in_fhands:
#         raise ValueError('At least one input fhand is required')
#     pairs = _read_pairs(in_fhands, paired_reads)
#     get_pair_key = _PairKeyGetter(use_length=use_length)
#     if n_seqs_packet is None:
#         unique_pairs = unique_unordered(pairs, key=get_pair_key)
#     else:
#         sorted_pairs = sorted_items(pairs, key=get_pair_key, tempdir=tempdir,
#                                     max_items_in_memory=n_seqs_packet)
#         unique_pairs = unique(sorted_pairs, key=get_pair_key)
#     for pair in unique_pairs:
#         write_seqs(pair, out_fhand)
# 
# def _read_pairs(in_fhands, paired_reads):
#     seqs = read_seqs(in_fhands, prefered_seq_classes=[SEQITEM])
#     if paired_reads:
#         pairs = group_pairs_by_name(seqs)
#     else:
#         pairs = group_pairs(seqs, n_seqs_in_pair=1)
#     return pairs
# 
# def _seqitem_pairs_equal(pair1, pair2):
#     if len(pair1) != len(pair2):
#         return False
#     else:
#         for read1, read2 in zip(pair1, pair2):
#             if not get_str_seq(read1) == get_str_seq(read2):
#                 return False
#         return True
# 
# Path: crumbs/utils/bin_utils.py
# SEQ_BIN_DIR = os.path.join(BIN_DIR, 'seq')
# 
# Path: crumbs/utils/test_utils.py
# TEST_DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
#                                              '..', 'test', 'test_data'))
# 
# Path: crumbs/exceptions.py
# class UndecidedFastqVersionError(Exception):
#     'The file is Fastq, but the version is difficult to guess'
#     pass
# 
# Path: crumbs/utils/file_utils.py
# def flush_fhand(fhand):
#     try:
#         fhand.flush()
#     except IOError, error:
#         # The pipe could be already closed
#         if 'Broken pipe' not in str(error):
#             raise


import unittest
import os
from subprocess import check_output
from tempfile import NamedTemporaryFile
from StringIO import StringIO
from crumbs.seq.seq import SeqWrapper, SeqItem
from crumbs.utils.tags import SEQITEM
from crumbs.seq.bulk_filters import (filter_duplicates, _read_pairs,
                                     _seqitem_pairs_equal)
from crumbs.utils.bin_utils import SEQ_BIN_DIR
from crumbs.utils.test_utils import TEST_DATA_DIR
from crumbs.exceptions import UndecidedFastqVersionError
from crumbs.utils.file_utils import flush_fhand
                                      paired_reads=False))
    assert len(filtered_pairs) == 2

    # use length
    in_fhand = NamedTemporaryFile()
    in_fhand.write(FASTQ_DUPS)
    in_fhand.flush()
    in_fhand = open(in_fhand.name)

    out_fhand = NamedTemporaryFile()
    filter_duplicates([in_fhand], out_fhand, paired_reads=False,
                      n_seqs_packet=n_seqs_packet, use_length=1)
    flush_fhand(out_fhand)
    filtered_pairs = list(_read_pairs([open(out_fhand.name)],
                                      paired_reads=False))
    assert len(filtered_pairs) == 1


class FilterDuplicatesTest(unittest.TestCase):

    def test_seqitem_pairs_equal(self):
        seq1 = SeqWrapper(SEQITEM, SeqItem('seq1',
                                           ['@seq1\n', 'TAATAC\n', '+\n',
                                            'TTTDFG\n']), 'fastq')
        seq2 = SeqWrapper(SEQITEM, SeqItem('seq2',
                                           ['@seq2\n', 'TCATTA\n', '+\n',
                                            'ABCBEG\n']), 'fastq')
        seq3 = SeqWrapper(SEQITEM, SeqItem('seq3',
                                           ['@seq3\n', 'TAATAC\n', '+\n',
                                            'TTTDFG\n']), 'fastq')

# Path: crumbs/seq/seq.py
# class SeqItem(_SeqItem):
#     def __new__(cls, name, lines, annotations=None):
# def get_title(seq):
# def get_description(seq):
# def get_name(seq):
# def get_file_format(seq):
# def _break():
# def _is_fastq_plus_line(line, seq_name):
# def _get_seqitem_quals(seq):
# def get_str_seq(seq):
# def get_length(seq):
# def _get_seqitem_qualities(seqwrap):
# def get_int_qualities(seq):
# def _int_quals_to_str_quals(int_quals, out_format):
# def get_str_qualities(seq, out_format=None):
# def get_annotations(seq):
# def _copy_seqrecord(seqrec, seq=None, name=None, id_=None):
# def _copy_seqitem(seqwrapper, seq=None, name=None):
# def copy_seq(seqwrapper, seq=None, name=None):
# def _slice_seqitem(seqwrap, start, stop):
# def slice_seq(seq, start=None, stop=None):
# def assing_kind_to_seqs(kind, seqs, file_format):
# SANGER_QUALS = {chr(i): i - 33 for i in range(33, 127)}
# ILLUMINA_QUALS = {chr(i): i - 64 for i in range(64, 127)}
# SANGER_STRS = {i - 33: chr(i)  for i in range(33, 127)}
# ILLUMINA_STRS = {i - 64: chr(i) for i in range(64, 127)}
# 
# Path: crumbs/utils/tags.py
# SEQITEM = 'seqitem'
# 
# Path: crumbs/seq/bulk_filters.py
# def filter_duplicates(in_fhands, out_fhand, paired_reads, use_length=None,
#                       n_seqs_packet=None, tempdir=None):
#     if not in_fhands:
#         raise ValueError('At least one input fhand is required')
#     pairs = _read_pairs(in_fhands, paired_reads)
#     get_pair_key = _PairKeyGetter(use_length=use_length)
#     if n_seqs_packet is None:
#         unique_pairs = unique_unordered(pairs, key=get_pair_key)
#     else:
#         sorted_pairs = sorted_items(pairs, key=get_pair_key, tempdir=tempdir,
#                                     max_items_in_memory=n_seqs_packet)
#         unique_pairs = unique(sorted_pairs, key=get_pair_key)
#     for pair in unique_pairs:
#         write_seqs(pair, out_fhand)
# 
# def _read_pairs(in_fhands, paired_reads):
#     seqs = read_seqs(in_fhands, prefered_seq_classes=[SEQITEM])
#     if paired_reads:
#         pairs = group_pairs_by_name(seqs)
#     else:
#         pairs = group_pairs(seqs, n_seqs_in_pair=1)
#     return pairs
# 
# def _seqitem_pairs_equal(pair1, pair2):
#     if len(pair1) != len(pair2):
#         return False
#     else:
#         for read1, read2 in zip(pair1, pair2):
#             if not get_str_seq(read1) == get_str_seq(read2):
#                 return False
#         return True
# 
# Path: crumbs/utils/bin_utils.py
# SEQ_BIN_DIR = os.path.join(BIN_DIR, 'seq')
# 
# Path: crumbs/utils/test_utils.py
# TEST_DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..',
#                                              '..', 'test', 'test_data'))
# 
# Path: crumbs/exceptions.py
# class UndecidedFastqVersionError(Exception):
#     'The file is Fastq, but the version is difficult to guess'
#     pass
# 
# Path: crumbs/utils/file_utils.py
# def flush_fhand(fhand):
#     try:
#         fhand.flush()
#     except IOError, error:
#         # The pipe could be already closed
#         if 'Broken pipe' not in str(error):
#             raise


# Path: test/seq/test_bulk_filters.py
import unittest
import os
from subprocess import check_output
from tempfile import NamedTemporaryFile
from StringIO import StringIO
from crumbs.seq.seq import SeqWrapper, SeqItem
from crumbs.utils.tags import SEQITEM
from crumbs.seq.bulk_filters import (filter_duplicates, _read_pairs,
                                     _seqitem_pairs_equal)
from crumbs.utils.bin_utils import SEQ_BIN_DIR
from crumbs.utils.test_utils import TEST_DATA_DIR
from crumbs.exceptions import UndecidedFastqVersionError
from crumbs.utils.file_utils import flush_fhand

                                      paired_reads=False))
    assert len(filtered_pairs) == 2

    # use length
    in_fhand = NamedTemporaryFile()
    in_fhand.write(FASTQ_DUPS)
    in_fhand.flush()
    in_fhand = open(in_fhand.name)

    out_fhand = NamedTemporaryFile()
    filter_duplicates([in_fhand], out_fhand, paired_reads=False,
                      n_seqs_packet=n_seqs_packet, use_length=1)
    flush_fhand(out_fhand)
    filtered_pairs = list(_read_pairs([open(out_fhand.name)],
                                      paired_reads=False))
    assert len(filtered_pairs) == 1


class FilterDuplicatesTest(unittest.TestCase):

    def test_seqitem_pairs_equal(self):
        seq1 = SeqWrapper(SEQITEM, SeqItem('seq1',
                                           ['@seq1\n', 'TAATAC\n', '+\n',
                                            'TTTDFG\n']), 'fastq')
        seq2 = SeqWrapper(SEQITEM, SeqItem('seq2',
                                           ['@seq2\n', 'TCATTA\n', '+\n',
                                            'ABCBEG\n']), 'fastq')
        seq3 = SeqWrapper(SEQITEM, SeqItem('seq3',
                                           ['@seq3\n', 'TAATAC\n', '+\n',
                                            'TTTDFG\n']), 'fastq')

        seq4 = SeqWrapper(SEQITEM, SeqItem('seq4',