#NEWLINE# def merge( iterator , max_distance = 0 , by_name = False , min_intervals = 1 , remove_inconsistent = False , resolve_blocks = False , stranded = False ) : #NEWLINE# #INDENT# 'iterator for merging adjacent bed entries.\n\n    *max_distance* > 0 permits merging of intervals that are\n    not directly adjacent.\n\n    If *by_name = True*, only entries with the same name are merged.\n\n    If *remove_inconsistent*, overlapping intervals where the names\n    are inconsistent will be removed.\n\n    The score gives the number of intervals that have been merged.\n    ' #NEWLINE# if ( remove_inconsistent and by_name ) : #NEWLINE# #INDENT# assert ValueError ( 'using both remove_inconsistent and by_name makes no sense' ) #NEWLINE# #UNINDENT# def iterate_chunks( iterator ) : #NEWLINE# #INDENT# max_end = defaultdict ( int ) #NEWLINE# to_join = defaultdict ( list ) #NEWLINE# last_name = defaultdict ( str ) #NEWLINE# last = iterator . next ( ) #NEWLINE# if ( not stranded ) : #NEWLINE# #INDENT# strand = '.' #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# strand = last . strand #NEWLINE# #UNINDENT# max_end [ strand ] = last . end #NEWLINE# to_join [ strand ] = [ last ] #NEWLINE# for bed in iterator : #NEWLINE# #INDENT# if ( not stranded ) : #NEWLINE# #INDENT# strand = '.' #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# strand = bed . strand #NEWLINE# #UNINDENT# d = ( bed . start - max_end [ strand ] ) #NEWLINE# if ( bed . contig == last . contig ) : #NEWLINE# #INDENT# assert ( bed . start >= last . start ) , ( 'input file should be sorted by contig and position: d=%i:\n%s\n%s\n' % ( d , last , bed ) ) #NEWLINE# #UNINDENT# if ( bed . contig != last . contig ) : #NEWLINE# #INDENT# for s in to_join : #NEWLINE# #INDENT# if to_join [ s ] : #NEWLINE# #INDENT# ( yield to_join [ s ] ) #NEWLINE# #UNINDENT# to_join [ s ] = [ ] #NEWLINE# max_end [ s ] = 0 #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( ( d > max_distance ) or ( by_name and ( last_name [ strand ] != bed . name ) ) ) : #NEWLINE# #INDENT# if to_join [ strand ] : #NEWLINE# #INDENT# ( yield to_join [ strand ] ) #NEWLINE# #UNINDENT# to_join [ strand ] = [ ] #NEWLINE# #UNINDENT# #UNINDENT# last = bed #NEWLINE# last_name [ strand ] = last . name #NEWLINE# max_end [ strand ] = max ( bed . end , max_end [ strand ] ) #NEWLINE# to_join [ strand ] . append ( bed ) #NEWLINE# #UNINDENT# for strand in to_join : #NEWLINE# #INDENT# if to_join [ strand ] : #NEWLINE# #INDENT# ( yield to_join [ strand ] ) #NEWLINE# #UNINDENT# #UNINDENT# raise StopIteration #NEWLINE# #UNINDENT# c = E . Counter ( ) #NEWLINE# for to_join in iterate_chunks ( iterator ) : #NEWLINE# #INDENT# c . input += 1 #NEWLINE# if remove_inconsistent : #NEWLINE# #INDENT# names = set ( [ x . name for x in to_join ] ) #NEWLINE# if ( len ( names ) > 1 ) : #NEWLINE# #INDENT# c . skipped_inconcistent_intervals += 1 #NEWLINE# continue #NEWLINE# #UNINDENT# #UNINDENT# if resolve_blocks : #NEWLINE# #INDENT# for bed in to_join : #NEWLINE# #INDENT# bed [ 'score' ] = 1 #NEWLINE# #UNINDENT# merged = True #NEWLINE# while merged : #NEWLINE# #INDENT# joined = [ ] #NEWLINE# not_joined = [ ] #NEWLINE# merged = False #NEWLINE# while ( len ( to_join ) > 0 ) : #NEWLINE# #INDENT# ( bed1 , to_join ) = ( to_join [ 0 ] , to_join [ 1 : ] ) #NEWLINE# intervals1 = bed1 . toIntervals ( ) #NEWLINE# for bed2 in to_join : #NEWLINE# #INDENT# intervals2 = bed2 . toIntervals ( ) #NEWLINE# if ( Intervals . calculateOverlap ( intervals1 , intervals2 ) > 0 ) : #NEWLINE# #INDENT# intervals = Intervals . combine ( ( intervals1 + intervals2 ) ) #NEWLINE# bed1 . fromIntervals ( intervals ) #NEWLINE# bed1 [ 'score' ] += bed2 [ 'score' ] #NEWLINE# merged = True #NEWLINE# #UNINDENT# else : #NEWLINE# #INDENT# not_joined . append ( bed2 ) #NEWLINE# #UNINDENT# #UNINDENT# joined . append ( bed1 ) #NEWLINE# to_join = not_joined #NEWLINE# not_joined = [ ] #NEWLINE# #UNINDENT# to_join = joined #NEWLINE# joined = [ ] #NEWLINE# #UNINDENT# to_join = sorted ( to_join , key = ( lambda x : int ( x . start ) ) ) #NEWLINE# for bed in to_join : #NEWLINE# #INDENT# if ( bed [ 'score' ] < by_name ) : #NEWLINE# #INDENT# c . skipped_min_intervals += 1 #NEWLINE# continue #NEWLINE# #UNINDENT# ( yield bed ) #NEWLINE# c . output += 1 #NEWLINE# #UNINDENT# #UNINDENT# else : #NEWLINE# #INDENT# if ( len ( to_join ) < min_intervals ) : #NEWLINE# #INDENT# c . skipped_min_intervals += 1 #NEWLINE# continue #NEWLINE# #UNINDENT# a = to_join [ 0 ] #NEWLINE# a . end = max ( [ entry . end for entry in to_join ] ) #NEWLINE# a . score = len ( to_join ) #NEWLINE# ( yield a ) #NEWLINE# c . output += 1 #NEWLINE# #UNINDENT# #UNINDENT# E . info ( str ( c ) )