# Path: crumbs/utils/optional_modules.py
# NCBIXML = create_fake_class(MSG + BIO)
# 
# Path: crumbs/utils/tags.py
# SUBJECT = 'subject'
# 
# QUERY = 'query'
# 
# ELONGATED = 'elongated'
# 
# Path: crumbs/utils/segments_utils.py
# def merge_overlaping_segments(segments, merge_segments_closer=1):
#     '''Given a list of segments it returns the overlapped segments.
# 
#        segments 1  -------        ----->    -----------
#        segments 2       ------
#        returns     -----------    ------    -----------
#        merge_segments_closer is an integer. Segments closer than the given
#        number of residues will be merged.
#     '''
# 
#     # we collect all start and ends
#     limits = []
#     for segment in segments:
#         start = segment[0]
#         end = segment[1]
#         if start > end:  # a reversed item
#             start, end = end, start
#         limit_1 = (START, start)
#         limit_2 = (END, end)
#         limits.append(limit_1)
#         limits.append(limit_2)
# 
#     # sort by secondary key: start before end
#     limits.sort(key=itemgetter(0))
#     # sort by location (primary key)
#     limits.sort(key=itemgetter(1))
# 
#     # merge the ends and start that differ in only one base
#     filtered_limits = []
#     previous_limit = None
#     for limit in limits:
#         if previous_limit is None:
#             previous_limit = limit
#             continue
#         if (previous_limit[0] == END and limit[0] == START and
#             previous_limit[1] >= limit[1] - merge_segments_closer):
#             # These limits cancelled each other
#             previous_limit = None
#             continue
#         filtered_limits.append(previous_limit)
#         previous_limit = limit
#     else:
#         filtered_limits.append(limit)
#     limits = filtered_limits
# 
#     # now we create the merged hsps
#     starts = 0
#     segments = []
#     for limit in limits:
#         if limit[0] == START:
#             starts += 1
#             if starts == 1:
#                 segment_start = limit[1]
#         elif limit[0] == END:
#             starts -= 1
#             if starts == 0:
#                 segment = (segment_start, limit[1])
#                 segments.append(segment)
#     return segments


import itertools
import copy
import os
from math import log10
from crumbs.utils.optional_modules import NCBIXML
from crumbs.utils.tags import SUBJECT, QUERY, ELONGATED
from crumbs.utils.segments_utils import merge_overlaping_segments
        fhand.seek(0, 0)
        sample = fhand.read(10)
        if sample and 'xml' not in sample:
            raise ValueError('Not a xml file')
        fhand.seek(0, 0)
        self._blast_file = fhand
        metadata = self._get_blast_metadata()
        blast_version = metadata['version']
        plus = metadata['plus']
        self.db_name = metadata['db_name']

        self._blast_file.seek(0, 0)

        if ((blast_version and plus) or
                                (blast_version and blast_version > '2.2.21')):
            self.use_query_def_as_accession = True
            self.use_subject_def_as_accession = True

        else:
            self.use_query_def_as_accession = True
            self.use_subject_def_as_accession = False

        if subj_def_as_accesion is not None:
            self.use_subject_def_as_accession = subj_def_as_accesion

        # we use the biopython parser
        # if there are no results we put None in our blast_parse results
        self._blast_parse = None
        if fhand.read(1) == '<':
            fhand.seek(0)

# Path: crumbs/utils/optional_modules.py
# NCBIXML = create_fake_class(MSG + BIO)
# 
# Path: crumbs/utils/tags.py
# SUBJECT = 'subject'
# 
# QUERY = 'query'
# 
# ELONGATED = 'elongated'
# 
# Path: crumbs/utils/segments_utils.py
# def merge_overlaping_segments(segments, merge_segments_closer=1):
#     '''Given a list of segments it returns the overlapped segments.
# 
#        segments 1  -------        ----->    -----------
#        segments 2       ------
#        returns     -----------    ------    -----------
#        merge_segments_closer is an integer. Segments closer than the given
#        number of residues will be merged.
#     '''
# 
#     # we collect all start and ends
#     limits = []
#     for segment in segments:
#         start = segment[0]
#         end = segment[1]
#         if start > end:  # a reversed item
#             start, end = end, start
#         limit_1 = (START, start)
#         limit_2 = (END, end)
#         limits.append(limit_1)
#         limits.append(limit_2)
# 
#     # sort by secondary key: start before end
#     limits.sort(key=itemgetter(0))
#     # sort by location (primary key)
#     limits.sort(key=itemgetter(1))
# 
#     # merge the ends and start that differ in only one base
#     filtered_limits = []
#     previous_limit = None
#     for limit in limits:
#         if previous_limit is None:
#             previous_limit = limit
#             continue
#         if (previous_limit[0] == END and limit[0] == START and
#             previous_limit[1] >= limit[1] - merge_segments_closer):
#             # These limits cancelled each other
#             previous_limit = None
#             continue
#         filtered_limits.append(previous_limit)
#         previous_limit = limit
#     else:
#         filtered_limits.append(limit)
#     limits = filtered_limits
# 
#     # now we create the merged hsps
#     starts = 0
#     segments = []
#     for limit in limits:
#         if limit[0] == START:
#             starts += 1
#             if starts == 1:
#                 segment_start = limit[1]
#         elif limit[0] == END:
#             starts -= 1
#             if starts == 0:
#                 segment = (segment_start, limit[1])
#                 segments.append(segment)
#     return segments


# Path: crumbs/seq/alignment_result.py
import itertools
import copy
import os
from math import log10
from crumbs.utils.optional_modules import NCBIXML
from crumbs.utils.tags import SUBJECT, QUERY, ELONGATED
from crumbs.utils.segments_utils import merge_overlaping_segments

        fhand.seek(0, 0)
        sample = fhand.read(10)
        if sample and 'xml' not in sample:
            raise ValueError('Not a xml file')
        fhand.seek(0, 0)
        self._blast_file = fhand
        metadata = self._get_blast_metadata()
        blast_version = metadata['version']
        plus = metadata['plus']
        self.db_name = metadata['db_name']

        self._blast_file.seek(0, 0)

        if ((blast_version and plus) or
                                (blast_version and blast_version > '2.2.21')):
            self.use_query_def_as_accession = True
            self.use_subject_def_as_accession = True

        else:
            self.use_query_def_as_accession = True
            self.use_subject_def_as_accession = False

        if subj_def_as_accesion is not None:
            self.use_subject_def_as_accession = subj_def_as_accesion

        # we use the biopython parser
        # if there are no results we put None in our blast_parse results
        self._blast_parse = None
        if fhand.read(1) == '<':
            fhand.seek(0)

            self._blast_parse = NCBIXML.parse(fhand)