def bucketIterator(elements, buckets):
def check_sorted(current, previous):<EOL><INDENT>if (previous is not None) and((previous.chrom > current.chrom) or<EOL>((previous.chrom == current.chrom) and<EOL>(previous.start > current.start))):<EOL><INDENT>raise GenomicIntervalError("<STR_LIT>" +<EOL>str(previous) + "<STR_LIT>" + str(current))<EOL><DEDENT><DEDENT>def updateOpen(openHeap, elementIterator, bucketChrom,<EOL>bucketStart, bucketEnd):<EOL><INDENT>"""<STR_LIT>"""<EOL>while len(openHeap) > <NUM_LIT:0> and ((openHeap[<NUM_LIT:0>].chrom < bucketChrom) or<EOL>((openHeap[<NUM_LIT:0>].chrom == bucketChrom) and<EOL>(openHeap[<NUM_LIT:0>].end <= bucketStart))):<EOL><INDENT>heappop(openHeap)<EOL><DEDENT>while (elementIterator.peek() is not None) and((elementIterator.peek().chrom < bucketChrom) or<EOL>((elementIterator.peek().chrom == bucketChrom) and<EOL>(elementIterator.peek().start < bucketEnd))):<EOL><INDENT>e = elementIterator.__next__()<EOL>if (e.chrom < bucketChrom) or(e.chrom == bucketChrom and e.end <= bucketStart):<EOL><INDENT>continue<EOL><DEDENT>heappush(openHeap, e)<EOL><DEDENT><DEDENT>openElems = []<EOL>prevBucket = None<EOL>elementIter = AutoApplyIterator(elements, check_sorted)<EOL>for bucket in buckets:<EOL><INDENT>if prevBucket is not None and ((bucket.chrom < prevBucket.chrom) or<EOL>(bucket.chrom == prevBucket.chrom and<EOL>bucket.start < prevBucket.start)):<EOL><INDENT>raise GenomicIntervalError("<STR_LIT>" +<EOL>str(prevBucket) + "<STR_LIT>" + str(bucket))<EOL><DEDENT>updateOpen(openElems, elementIter, bucket.chrom, bucket. start, bucket.end)<EOL>yield bucket, [x for x in openElems if x.start < bucket.end]<EOL>prevBucket = bucket<EOL><DEDENT>
For each bucket in buckets, yield it and any elements that overlap it.

:param elements: the genomic intervals to place into the buckets. Must be
                 sorted by chromosome and start index. This could be a
                 list, or an iterator.
:param buckets: the buckets into which genomic intervals should be binned.
                Must be sorted by chromosome and start index. This could be
                a list, or an iterator
:return: iterator that will yeild a tuple of 1 bucket and 1 list of elements
         in the bucket for each call to __next__().