def pairedWigIterator(inputStreams, mirror=False, mirrorScore=None,
                      ignoreScore=True, sortedby=ITERATOR_SORTED_END,
                      scoreType=int, verbose=False, debug=False):
  """
    @summary: iterate over multiple wig streams, and yield a list of wig
              elements that match for each location (locations with 0 matching
              items are skipped)
    @param inputStrams: TODO
    @param mirror:      TODO
    @param mirrorScore: TODO
    @param ignoreScore: Don't consider score when determining if two elements
                        are equal
    @param sortedby:    TODO
    @param scoreType:   TODO
    @param verbose:     TODO
    @param debug:       TODO
    @note: streams must be sorted -- sortedby parameter determines what sorting
           order will be acceptable
  """
  # let's build our sorting order...
  sortOrder = ["chrom"]
  if sortedby == ITERATOR_SORTED_START:
    sortOrder.append("start")
    sortOrder.append("end")
  elif sortedby == ITERATOR_SORTED_END:
    sortOrder.append("end")
    sortOrder.append("start")
  if not ignoreScore:
    sortOrder.append("score")
  keyFunc = attrgetter(*sortOrder)

  def next_item(iterator):
    """ little internal function to return the next item, or None """
    try:
      return iterator.next()
    except StopIteration:
      return None

  wIterators = [wigIterator(fh, verbose=verbose, sortedby=sortedby,
                            scoreType=scoreType) for fh in inputStreams]
  elements = [next_item(it) for it in wIterators]

  while True:
    assert(len(elements) >= 2)
    if None not in elements and len(set([keyFunc(x) for x in elements])) == 1:
      # All equal -- yield and move on for all streams
      yield [e for e in elements]
      elements = [next_item(it) for it in wIterators]
    else:
      # something wasn't equal.... find the smallest thing, it's about
      # to drop out of range...
      minElement = min([x for x in elements if x is not None], key=keyFunc)
      minIndices = [i for i in range(0, len(elements))
                    if elements[i] is not None and
                    keyFunc(elements[i]) == keyFunc(minElement)]
      if mirror:
        # mirror the min item for any streams in which it doesn't match
        score = minElement.score if mirrorScore is None else mirrorScore
        yield [elements[i] if i in minIndices
               else GenomicInterval(minElement.chrom, minElement.start,
                                    minElement.end, None, score)
               for i in range(0, len(elements))]

      # move the smallest element onwards now, we're done with it
      for index in minIndices:
        elements[index] = next_item(wIterators[index])

    # stop once all strams are exhuasted
    if reduce(lambda x, y: x and y, [e is None for e in elements]):
      break
def pairedWigIterator ( inputStreams , mirror = False , mirrorScore = None , ignoreScore = True , sortedby = ITERATOR_SORTED_END , scoreType = int , verbose = False , debug = False ) : sortOrder = [ "chrom" ] if sortedby == ITERATOR_SORTED_START : sortOrder . append ( "start" ) sortOrder . append ( "end" ) elif sortedby == ITERATOR_SORTED_END : sortOrder . append ( "end" ) sortOrder . append ( "start" ) if not ignoreScore : sortOrder . append ( "score" ) keyFunc = attrgetter ( * sortOrder ) def next_item ( iterator ) : try : return iterator . next ( ) except StopIteration : return None wIterators = [ wigIterator ( fh , verbose = verbose , sortedby = sortedby , scoreType = scoreType ) for fh in inputStreams ] elements = [ next_item ( it ) for it in wIterators ] while True : assert ( len ( elements ) >= 2 ) if None not in elements and len ( set ( [ keyFunc ( x ) for x in elements ] ) ) == 1 : yield [ e for e in elements ] elements = [ next_item ( it ) for it in wIterators ] else : minElement = min ( [ x for x in elements if x is not None ] , key = keyFunc ) minIndices = [ i for i in range ( 0 , len ( elements ) ) if elements [ i ] is not None and keyFunc ( elements [ i ] ) == keyFunc ( minElement ) ] if mirror : score = minElement . score if mirrorScore is None else mirrorScore yield [ elements [ i ] if i in minIndices else GenomicInterval ( minElement . chrom , minElement . start , minElement . end , None , score ) for i in range ( 0 , len ( elements ) ) ] for index in minIndices : elements [ index ] = next_item ( wIterators [ index ] ) if reduce ( lambda x , y : x and y , [ e is None for e in elements ] ) : break
@summary: iterate over multiple wig streams, and yield a list of wig
              elements that match for each location (locations with 0 matching
              items are skipped)
    @param inputStrams: TODO
    @param mirror:      TODO
    @param mirrorScore: TODO
    @param ignoreScore: Don't consider score when determining if two elements
                        are equal
    @param sortedby:    TODO
    @param scoreType:   TODO
    @param verbose:     TODO
    @param debug:       TODO
    @note: streams must be sorted -- sortedby parameter determines what sorting
           order will be acceptable