def _get_read_names(self, search_result, max_range):
splits = {}  <EOL>spans = []<EOL>for result in search_result:  <EOL><INDENT>spans += list(<EOL>result.each(<EOL>[SequenceSearchResult.QUERY_ID_FIELD,<EOL>SequenceSearchResult.ALIGNMENT_DIRECTION,<EOL>SequenceSearchResult.HIT_FROM_FIELD,<EOL>SequenceSearchResult.HIT_TO_FIELD,<EOL>SequenceSearchResult.QUERY_FROM_FIELD,<EOL>SequenceSearchResult.QUERY_TO_FIELD]<EOL>)<EOL>)<EOL><DEDENT>for hit in spans:  <EOL><INDENT>i = hit[<NUM_LIT:0>]  <EOL>c = hit[<NUM_LIT:1>]  <EOL>ft = [min(hit[<NUM_LIT:2>:<NUM_LIT:4>]), max(hit[<NUM_LIT:2>:<NUM_LIT:4>])]  <EOL>qs = [min(hit[<NUM_LIT:4>:<NUM_LIT:6>]), max(hit[<NUM_LIT:4>:<NUM_LIT:6>])]  <EOL>if ft[<NUM_LIT:0>] == ft[<NUM_LIT:1>]: continue  <EOL>if i not in splits:  <EOL><INDENT>splits[i] = {'<STR_LIT>'       : [ft],<EOL>'<STR_LIT>'     : [c],<EOL>'<STR_LIT>' : [qs]}  <EOL><DEDENT>else:  <EOL><INDENT>for idx, entry in enumerate(splits[i]['<STR_LIT>']):  <EOL><INDENT>if splits[i]['<STR_LIT>'][idx] != c:  <EOL><INDENT>splits[i]['<STR_LIT>'].append(ft)  <EOL>splits[i]['<STR_LIT>'].append(c)  <EOL>splits[i]['<STR_LIT>'].append(qs)<EOL>break<EOL><DEDENT>previous_qs      = splits[i]['<STR_LIT>'][idx] <EOL>previous_q_range = set(range(previous_qs[<NUM_LIT:0>], previous_qs[<NUM_LIT:1>])) <EOL>current_q_range  = set(range(qs[<NUM_LIT:0>], qs[<NUM_LIT:1>]))<EOL>query_overlap    = set(previous_q_range).intersection(current_q_range) <EOL>previous_ft_span = set(range(entry[<NUM_LIT:0>], entry[<NUM_LIT:1>]))<EOL>current_ft_span  = set(range(ft[<NUM_LIT:0>], ft[<NUM_LIT:1>]))<EOL>if any(query_overlap): <EOL><INDENT>intersection_fraction = float(len(previous_ft_span.intersection(current_ft_span)))<EOL>if intersection_fraction / float(len(previous_ft_span)) >= PREVIOUS_SPAN_CUTOFF:<EOL><INDENT>break<EOL><DEDENT>elif intersection_fraction / float(len(current_ft_span)) >= PREVIOUS_SPAN_CUTOFF:<EOL><INDENT>break<EOL><DEDENT>else: <EOL><INDENT>if len(query_overlap) > (len(current_q_range)*PREVIOUS_SPAN_CUTOFF): <EOL><INDENT>if (idx+<NUM_LIT:1>) == len(splits[i]['<STR_LIT>']):<EOL><INDENT>splits[i]['<STR_LIT>'].append(ft) <EOL>splits[i]['<STR_LIT>'].append(c) <EOL>splits[i]['<STR_LIT>'].append(qs)<EOL>break <EOL><DEDENT><DEDENT><DEDENT><DEDENT>if min(entry) < min(ft):  <EOL><INDENT>if max(ft) - min(entry) < max_range:  <EOL><INDENT>entry[<NUM_LIT:1>] = max(ft)  <EOL>break  <EOL><DEDENT><DEDENT>else:<EOL><INDENT>if max(entry) - min(ft) < max_range:  <EOL><INDENT>entry[<NUM_LIT:0>] = min(ft)  <EOL>break  <EOL><DEDENT><DEDENT><DEDENT>else:  <EOL><INDENT>splits[i]['<STR_LIT>'].append(ft)  <EOL>splits[i]['<STR_LIT>'].append(c)  <EOL>splits[i]['<STR_LIT>'].append(qs)<EOL><DEDENT><DEDENT><DEDENT>return {key: {"<STR_LIT>":entry['<STR_LIT>'], '<STR_LIT>': entry['<STR_LIT>']} for key, entry in splits.iteritems()}<EOL>
_get_read_names - loops through hmm hits and their alignment spans to
determine if they are potentially linked (for example, if one gene in a 
contig hits a hmm more than once, in two different conserved regions
of that gene) and combines them into one 'hit' because they are
technically the same. The total span of the hits deemed to be linked is
returned.

Parameters
----------
search_result : obj
    SequenceSearchResult object with all paramaters defined. Used here
    to create rows containing information on alignment direction and
    alignment span.
max_range : int
    Maximum range that a gene can extend within a contig. Any hits
    that extend beyond this length cannot be linked. max_range is
    set as 1.5 X the average length of all full length genes used
    in the search database. This is defined in the CONTENTS.json file
    within a gpkg.
Returns
-------
    Dictionary where keys are the contig/read name. The value for each
    entry is an array lists, one per hit in each contig, each with the
    span (min and max) of the alignment.