def BEDDuplicateIterator(fh1, fh2, removeJuncTags=False, removePETags=False,<EOL>verbose=False):
if removePETags and not removeJuncTags:<EOL><INDENT>raise BEDError("<STR_LIT>"<EOL>+ "<STR_LIT>")<EOL><DEDENT>def next_item(iterator):<EOL><INDENT>"""<STR_LIT>"""<EOL>try:<EOL><INDENT>return next(iterator)<EOL><DEDENT>except StopIteration:<EOL><INDENT>return None<EOL><DEDENT><DEDENT>def name(read):<EOL><INDENT>name = read.name<EOL>if removeJuncTags and name[-<NUM_LIT:2>] == "<STR_LIT:%>":<EOL><INDENT>name = name[:-<NUM_LIT:2>]<EOL><DEDENT>if removePETags and name[-<NUM_LIT:2>] == "<STR_LIT:.>":<EOL><INDENT>name = name[:-<NUM_LIT:2>]<EOL><DEDENT>return name<EOL><DEDENT>def match(read, list1, list2):<EOL><INDENT>"""<STR_LIT>"""<EOL>for r in list1:<EOL><INDENT>if name(r) != name(read):<EOL><INDENT>return False<EOL><DEDENT><DEDENT>for r in list2:<EOL><INDENT>if name(r) != name(read):<EOL><INDENT>return False<EOL><DEDENT><DEDENT>return True<EOL><DEDENT>bit1 = BEDIterator(fh1, sortedby=ITERATOR_SORTED_NAME, verbose=verbose)<EOL>bit2 = BEDIterator(fh2, sortedby=ITERATOR_SORTED_NAME, verbose=verbose)<EOL>bf1, bf2 = None, None<EOL>bf1List, bf2List = [], []<EOL>while True:<EOL><INDENT>if bf1 is None:<EOL><INDENT>bf1 = next_item(bit1)<EOL><DEDENT>if bf2 is None:<EOL><INDENT>bf2 = next_item(bit2)<EOL><DEDENT>if bf1 is not None and (bf2 is None or name(bf1) < name(bf2)):<EOL><INDENT>if not match(bf1, bf1List, bf2List):<EOL><INDENT>yield (bf1List, bf2List)<EOL>bf1List, bf2List = [], []<EOL><DEDENT>bf1List.append(bf1)<EOL>bf1 = next_item(bit1)<EOL><DEDENT>elif bf2 is not None and (bf1 is None or name(bf2) < name(bf1)):<EOL><INDENT>if not match(bf2, bf1List, bf2List):<EOL><INDENT>yield (bf1List, bf2List)<EOL>bf1List, bf2List = [], []<EOL><DEDENT>bf2List.append(bf2)<EOL>bf2 = next_item(bit2)<EOL><DEDENT>elif bf1 is not None and bf2 is not None and name(bf1) == name(bf2):<EOL><INDENT>if not match(bf2, bf1List, bf2List):<EOL><INDENT>yield (bf1List, bf2List)<EOL>bf1List, bf2List = [], []<EOL><DEDENT>bf1List.append(bf1)<EOL>bf2List.append(bf2)<EOL>bf1 = next_item(bit1)<EOL>bf2 = next_item(bit2)<EOL><DEDENT>if bf1 is None and bf2 is None:<EOL><INDENT>if bf1List != [] or bf2List is not None:<EOL><INDENT>yield (bf1List, bf2List)<EOL>bf1List, bf2List = [], []<EOL><DEDENT>break<EOL><DEDENT><DEDENT>
@summary: returns an iterator which yields pairs of reads from fh1
          and fh2 such that duplicate reads (same name) are included
          in the same pair, while unique reads are paired with None.
          Reads from fh1 will always be first in the tuple, while reads
          from fh2 will always be second.
@param fh1: BED formated stream, must be sorted by name
@param fh2: BED formated stream, must be sorted by name
@param removeJuncTags: if True, remove the junctions tags added to the
                       read names by juncConvert (if present) before
                       comparing names (output reads will still have them)
@param removePETags: if True, remove the paired end tags of the read names
                     before comparing.
@param verbose: output additional progress messages to stderr if this
                is True
@note: it is assumed that PE tags are .1 or .2 and junc tags are %1 or %2
       and that junc tags will appear after PE tags