civicpy/civic.py
def bulk_search_variants_by_coordinates(sorted_queries, search_mode='any'):
    """
    An interator to search the cache for variants matching the set of sorted coordinates and yield
    matches corresponding to the search mode.

    :param sorted_queries:  A list of civic CoordinateQuery objects, sorted by coordinate.
                            start: the genomic start coordinate of the query
                            stop: the genomic end coordinate of the query
                            chr: the GRCh37 chromosome of the query (e.g. "7", "X")
                            alt: the alternate allele at the coordinate [optional]

    :param search_mode: ['any', 'include_smaller', 'include_larger', 'exact']
                        any: any overlap between a query and a variant is a match
                        include_smaller: variants must fit within the coordinates of the query
                        include_larger: variants must encompass the coordinates of the query
                        exact: variants must match coordinates precisely, as well as alternate
                               allele, if provided
                        search_mode is 'exact' by default

    :yield:            Yields (query, match) tuples for each identified match
    """

    def is_sorted(prev_q, current_q):
        if prev_q['chr'] < current_q['chr']:
            return True
        if prev_q['chr'] > current_q['chr']:
            return False
        if prev_q['start'] < current_q['start']:
            return True
        if prev_q['start'] > current_q['start']:
            return False
        if prev_q['stop'] < current_q['stop']:
            return True
        if prev_q['stop'] > current_q['stop']:
            return False
        return True

    ct_pointer = 0
    query_pointer = 0
    last_query_pointer = -1
    match_start = None
    ct = MODULE.COORDINATE_TABLE
    matches = defaultdict(list)
    Match = namedtuple('Match', ct.columns)
    while query_pointer < len(sorted_queries) and ct_pointer < len(ct):
        if last_query_pointer != query_pointer:
            q = sorted_queries[query_pointer]
            if match_start is not None:
                ct_pointer = match_start
                match_start = None
            last_query_pointer = query_pointer
        c = ct.iloc[ct_pointer]
        q_chr = str(q.chr)
        c_chr = c.chr
        if q_chr < c_chr:
            query_pointer += 1
            continue
        if q_chr > c_chr:
            ct_pointer += 1
            continue
        q_start = int(q.start)
        c_start = c.start
        q_stop = int(q.stop)
        c_stop = c.stop
        if q_start > c_stop:
            ct_pointer += 1
            continue
        if q_stop < c_start:
            query_pointer += 1
            continue
        if search_mode == 'any':
            matches[q].append(c.to_dict())
        elif search_mode == 'exact' and q_start == c_start and q_stop == c_stop:
            q_alt = q.alt
            c_alt = c.alt
            if not (q_alt and c_alt and q_alt != c_alt):
                matches[q].append(Match(**c.to_dict()))
        elif search_mode == 'include_smaller':
            raise NotImplementedError
        elif search_mode == 'include_larger':
            raise NotImplementedError
        if match_start is None:
            match_start = ct_pointer
        ct_pointer += 1
    return dict(matches)
def bulk_search_variants_by_coordinates(sorted_queries, search_mode='any'):
    """
    An interator to search the cache for variants matching the set of sorted coordinates and yield
    matches corresponding to the search mode.

    :param sorted_queries:  A list of civic CoordinateQuery objects, sorted by coordinate.
                            start: the genomic start coordinate of the query
                            stop: the genomic end coordinate of the query
                            chr: the GRCh37 chromosome of the query (e.g. "7", "X")
                            alt: the alternate allele at the coordinate [optional]

    :param search_mode: ['any', 'include_smaller', 'include_larger', 'exact']
                        any: any overlap between a query and a variant is a match
                        include_smaller: variants must fit within the coordinates of the query
                        include_larger: variants must encompass the coordinates of the query
                        exact: variants must match coordinates precisely, as well as alternate
                               allele, if provided
                        search_mode is 'exact' by default

    :yield:            Yields (query, match) tuples for each identified match
    """

    def is_sorted(prev_q, current_q):
        if prev_q['chr'] < current_q['chr']:
            return True
        if prev_q['chr'] > current_q['chr']:
            return False
        if prev_q['start'] < current_q['start']:
            return True
        if prev_q['start'] > current_q['start']:
            return False
        if prev_q['stop'] < current_q['stop']:
            return True
        if prev_q['stop'] > current_q['stop']:
            return False
        return True

    ct_pointer = 0
    query_pointer = 0
    last_query_pointer = -1
    match_start = None
    ct = MODULE.COORDINATE_TABLE
    matches = defaultdict(list)
    Match = namedtuple('Match', ct.columns)
    while query_pointer < len(sorted_queries) and ct_pointer < len(ct):
        if last_query_pointer != query_pointer:
            q = sorted_queries[query_pointer]
            if match_start is not None:
                ct_pointer = match_start
                match_start = None
            last_query_pointer = query_pointer
        c = ct.iloc[ct_pointer]
        q_chr = str(q.chr)
        c_chr = c.chr
        if q_chr < c_chr:
            query_pointer += 1
            continue
        if q_chr > c_chr:
            ct_pointer += 1
            continue
        q_start = int(q.start)
        c_start = c.start
        q_stop = int(q.stop)
        c_stop = c.stop
        if q_start > c_stop:
            ct_pointer += 1
            continue
        if q_stop < c_start:
            query_pointer += 1
            continue
        if search_mode == 'any':
            matches[q].append(c.to_dict())
        elif search_mode == 'exact' and q_start == c_start and q_stop == c_stop:
            q_alt = q.alt
            c_alt = c.alt
            if not (q_alt and c_alt and q_alt != c_alt):
                matches[q].append(Match(**c.to_dict()))
        elif search_mode == 'include_smaller':
            raise NotImplementedError
        elif search_mode == 'include_larger':
            raise NotImplementedError
        if match_start is None:
            match_start = ct_pointer
        ct_pointer += 1
    return dict(matches)
An interator to search the cache for variants matching the set of sorted coordinates and yield
    matches corresponding to the search mode.

    :param sorted_queries:  A list of civic CoordinateQuery objects, sorted by coordinate.
                            start: the genomic start coordinate of the query
                            stop: the genomic end coordinate of the query
                            chr: the GRCh37 chromosome of the query (e.g. "7", "X")
                            alt: the alternate allele at the coordinate [optional]

    :param search_mode: ['any', 'include_smaller', 'include_larger', 'exact']
                        any: any overlap between a query and a variant is a match
                        include_smaller: variants must fit within the coordinates of the query
                        include_larger: variants must encompass the coordinates of the query
                        exact: variants must match coordinates precisely, as well as alternate
                               allele, if provided
                        search_mode is 'exact' by default

    :yield:            Yields (query, match) tuples for each identified match