def repeat_masker_alignment_iterator(fn, index_friendly=True, verbose=False):
<EOL>try:<EOL><INDENT>fh = open(fn)<EOL><DEDENT>except (TypeError):<EOL><INDENT>fh = fn<EOL><DEDENT>iterable = fh<EOL>if index_friendly:<EOL><INDENT>iterable = iter(fh.readline, '<STR_LIT>')<EOL><DEDENT>if verbose:<EOL><INDENT>try:<EOL><INDENT>m_fn = "<STR_LIT>" + fh.name<EOL><DEDENT>except TypeError:<EOL><INDENT>m_fn = "<STR_LIT>"<EOL><DEDENT>try:<EOL><INDENT>current = fh.tell()<EOL>fh.seek(<NUM_LIT:0>, <NUM_LIT:2>)<EOL>total_progress = fh.tell()<EOL>fh.seek(current)<EOL>pind = ProgressIndicator(totalToDo=total_progress,<EOL>messagePrefix="<STR_LIT>",<EOL>messageSuffix="<STR_LIT>"<EOL>"<STR_LIT>" + m_fn)<EOL><DEDENT>except IOError:<EOL><INDENT>pind = None<EOL><DEDENT><DEDENT>old_fh_pos = None<EOL>new_fh_pos = fh.tell()<EOL>s1 = None<EOL>s2 = None<EOL>s1_name = None<EOL>s2_name = None<EOL>s1_start = None<EOL>s1_end = None<EOL>s2_start = None<EOL>s2_end = None<EOL>meta_data = None<EOL>alignment_line_counter = <NUM_LIT:0><EOL>alig_l_space = <NUM_LIT:0><EOL>prev_seq_len = <NUM_LIT:0><EOL>rev_comp_match = None<EOL>remaining_repeat = None<EOL>remaining_genomic = None<EOL>for line in iterable:<EOL><INDENT>if verbose and pind is not None:<EOL><INDENT>pind.done = fh.tell()<EOL>pind.showProgress()<EOL><DEDENT>if index_friendly:<EOL><INDENT>old_fh_pos = new_fh_pos<EOL>new_fh_pos = fh.tell()<EOL><DEDENT>line = line.rstrip()<EOL>if line.lstrip() == "<STR_LIT>" and alignment_line_counter % <NUM_LIT:3> != <NUM_LIT:1>:<EOL><INDENT>continue<EOL><DEDENT>s_pres_split = re.split(r'<STR_LIT>', line)<EOL>parts = [x for x in s_pres_split if not (x.isspace() or x == "<STR_LIT>")]<EOL>n = len(parts)<EOL>for i in REPEATMASKER_FIELDS_TO_TRIM:<EOL><INDENT>if n >= i + <NUM_LIT:1>:<EOL><INDENT>parts[i] = parts[i].strip()<EOL><DEDENT><DEDENT>if alignment_line_counter % <NUM_LIT:3> == <NUM_LIT:1>:<EOL><INDENT>if (REPEATMASKER_VALIDATE_MUTATIONS and<EOL>not _rm_is_valid_annotation_line(line)):<EOL><INDENT>raise IOError("<STR_LIT>" + line)<EOL><DEDENT>l_space = _rm_compute_leading_space(s_pres_split) - alig_l_space<EOL>pad_right = prev_seq_len - (l_space + len(line.strip()))<EOL>meta_data[ANNOTATION_KEY] += (('<STR_LIT:U+0020>' * l_space) + line.strip() +<EOL>('<STR_LIT:U+0020>' * pad_right))<EOL>alignment_line_counter += <NUM_LIT:1><EOL><DEDENT>elif _rm_is_header_line(parts, n):<EOL><INDENT>if not (s1 is None and s2 is None and meta_data is None):<EOL><INDENT>if ANNOTATION_KEY in meta_data:<EOL><INDENT>meta_data[ANNOTATION_KEY] = meta_data[ANNOTATION_KEY].rstrip()<EOL><DEDENT>if index_friendly:<EOL><INDENT>fh.seek(old_fh_pos)<EOL><DEDENT>ss1 = Sequence(s1_name, s1, s1_start, s1_end, "<STR_LIT:+>", remaining_genomic)<EOL>s2s = "<STR_LIT:->" if rev_comp_match else "<STR_LIT:+>"<EOL>ss2 = Sequence(s2_name, s2, s2_start, s2_end, s2s, remaining_repeat)<EOL>yield PairwiseAlignment(ss1, ss2, meta_data)<EOL>if index_friendly:<EOL><INDENT>fh.seek(new_fh_pos)<EOL><DEDENT><DEDENT>meta_data = {}<EOL>s1 = "<STR_LIT>"<EOL>s2 = "<STR_LIT>"<EOL>s1_name, s2_name = _rm_get_names_from_header(parts)<EOL>s1_start, s1_end = _rm_get_reference_coords_from_header(parts)<EOL>s2_start, s2_end = _rm_get_repeat_coords_from_header(parts)<EOL>rev_comp_match = _rm_is_reverse_comp_match(parts)<EOL>remaining_repeat = _rm_get_remaining_repeat_from_header(parts)<EOL>remaining_genomic = _rm_get_remaining_genomic_from_header(parts)<EOL>_rm_parse_header_line(parts, meta_data)<EOL>alignment_line_counter = <NUM_LIT:0><EOL><DEDENT>elif _rm_is_alignment_line(parts, s1_name, s2_name):<EOL><INDENT>alignment_line_counter += <NUM_LIT:1><EOL>name, seq = _rm_extract_sequence_and_name(parts, s1_name, s2_name)<EOL>if name == s1_name:<EOL><INDENT>s1 += seq<EOL><DEDENT>elif name == s2_name:<EOL><INDENT>s2 += seq<EOL><DEDENT>alig_l_space = _rm_compute_leading_space_alig(s_pres_split, seq)<EOL>prev_seq_len = len(seq)<EOL><DEDENT>else:<EOL><INDENT>k, v = _rm_parse_meta_line(parts)<EOL>meta_data[k] = v<EOL><DEDENT><DEDENT>if index_friendly:<EOL><INDENT>fh.seek(old_fh_pos)<EOL><DEDENT>ss1 = Sequence(s1_name, s1, s1_start, s1_end, "<STR_LIT:+>", remaining_genomic)<EOL>s2s = "<STR_LIT:->" if rev_comp_match else "<STR_LIT:+>"<EOL>ss2 = Sequence(s2_name, s2, s2_start, s2_end, s2s, remaining_repeat)<EOL>yield PairwiseAlignment(ss1, ss2, meta_data)<EOL>if index_friendly:<EOL><INDENT>fh.seek(new_fh_pos)<EOL><DEDENT>
Iterator for repeat masker alignment files; yields multiple alignment objects.

Iterate over a file/stream of full repeat alignments in the repeatmasker
format. Briefly, this format is as follows: each record (alignment) begins
with a header line (see _rm_parse_header_line documentation for details of
header format), followed by the alignment itself (example below) and finally
a set of key-value meta-data pairs.

The actual alignment looks like this::

  chr1               11 CCCTGGAGATTCTTATT--AGTGATTTGGGCT 41
                           ii        v   -- v  i i    v
  C MER5B#DNA/hAT    10 CCCCAGAGATTCTGATTTAATTGGTCTGGGGT 42

  chr1               42 GACTG 47
                         v
  C MER5B#DNA/hAT    43 CACTG 48

The 'C' indicates that its the reverse complement of the consensus. The
central string gives information about matches; "-" indicates an
insertion/deletion, "i" a transition (G<->A, C<->T) and "v" a transversion
(all other substitutions).

:param fh:             filename or stream-like object to read from.
:param index_friendly: if True, we will ensure the file/stream
                       position is before the start of the record when we
                       yield it; this requires the ability to seek within
                       the stream though, so if iterating over a
                       stream wtihout that ability, you'll have to set this
                       to false. Further, this will disable buffering for
                       the file, to ensure file.tell() behaves correctly,
                       so a performance hit will be incurred.
:param verbose:        if true, output progress messages to stderr.