<s> import os <EOL> import ngsutils . support . ngs_utils <EOL> import pysam <EOL> class BedStreamer ( object ) : <EOL> '''<STR_LIT>''' <EOL> def __init__ ( self , fname = None , fileobj = None , quiet = False ) : <EOL> if not fname and not fileobj : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> self . reader = ngsutils . support . gzip_reader ( fname = fname , quiet = quiet , fileobj = fileobj ) <EOL> def __iter__ ( self ) : <EOL> return self <EOL> def next ( self ) : <EOL> try : <EOL> while True : <EOL> line = self . reader . next ( ) . strip ( ) <EOL> if line and line [ <NUM_LIT:0> ] != '<STR_LIT:#>' : <EOL> cols = line . split ( '<STR_LIT:\t>' ) <EOL> while len ( cols ) < <NUM_LIT:6> : <EOL> cols . append ( '<STR_LIT>' ) <EOL> return BedRegion ( * cols ) <EOL> except : <EOL> raise StopIteration <EOL> class BedFile ( object ) : <EOL> '''<STR_LIT>''' <EOL> _bin_const = <NUM_LIT> <EOL> def __init__ ( self , fname = None , fileobj = None , region = None ) : <EOL> self . _bins = { } <EOL> self . _bin_list = [ ] <EOL> self . _cur_bin_idx = <NUM_LIT:0> <EOL> self . _cur_bin_pos = <NUM_LIT:0> <EOL> self . _tellpos = <NUM_LIT:0> <EOL> self . _total = <NUM_LIT:0> <EOL> self . _length = <NUM_LIT:0> <EOL> self . __tabix = None <EOL> self . filename = fname <EOL> if os . path . exists ( '<STR_LIT>' % fname ) : <EOL> self . __tabix = pysam . Tabixfile ( fname ) <EOL> if fileobj : <EOL> self . __readfile ( fileobj ) <EOL> elif fname : <EOL> with ngsutils . support . ngs_utils . gzip_opener ( fname ) as fobj : <EOL> self . __readfile ( fobj ) <EOL> elif region : <EOL> chrom , startend = region . split ( '<STR_LIT::>' ) <EOL> if '<STR_LIT:->' in startend : <EOL> start , end = [ int ( x ) for x in startend . split ( '<STR_LIT:->' ) ] <EOL> else : <EOL> start = int ( startend ) <EOL> end = start <EOL> start -= <NUM_LIT:1> <EOL> self . __add_region ( BedRegion ( chrom , start , end ) ) <EOL> else : <EOL> raise ValueError ( "<STR_LIT>" ) <EOL> def __readfile ( self , fobj ) : <EOL> for line in fobj : <EOL> line = line . strip ( ) <EOL> if line and line [ <NUM_LIT:0> ] != '<STR_LIT:#>' : <EOL> cols = line . split ( '<STR_LIT:\t>' ) <EOL> while len ( cols ) < <NUM_LIT:6> : <EOL> cols . append ( '<STR_LIT>' ) <EOL> region = BedRegion ( * cols ) <EOL> self . __add_region ( region ) <EOL> self . _bin_list . sort ( ) <EOL> for bin in self . _bins : <EOL> self . _bins [ bin ] . sort ( ) <EOL> def __add_region ( self , region ) : <EOL> self . _total += region . end - region . start <EOL> self . _length += <NUM_LIT:1> <EOL> startbin = region . start / BedFile . _bin_const <EOL> endbin = region . end / BedFile . _bin_const <EOL> for bin in xrange ( startbin , endbin + <NUM_LIT:1> ) : <EOL> if not ( region . chrom , bin ) in self . _bins : <EOL> self . _bin_list . append ( ( region . chrom , bin ) ) <EOL> self . _bins [ ( region . chrom , bin ) ] = [ ] <EOL> self . _bins [ ( region . chrom , bin ) ] . append ( region ) <EOL> def fetch ( self , chrom , start , end , strand = None ) : <EOL> '''<STR_LIT>''' <EOL> if self . __tabix : <EOL> for match in self . __tabix . fetch ( chrom , start , end ) : <EOL> region = BedRegion ( * match . split ( '<STR_LIT:\t>' ) ) <EOL> if not strand or ( strand and region . strand == strand ) : <EOL> yield region <EOL> else : <EOL> startbin = start / BedFile . _bin_const <EOL> endbin = end / BedFile . _bin_const <EOL> buf = set ( ) <EOL> for bin in xrange ( startbin , endbin + <NUM_LIT:1> ) : <EOL> if ( chrom , bin ) in self . _bins : <EOL> for region in self . _bins [ ( chrom , bin ) ] : <EOL> if strand and strand != region . strand : <EOL> continue <EOL> if start <= region . start <= end or start <= region . end <= end : <EOL> if not region in buf : <EOL> yield region <EOL> buf . add ( region ) <EOL> elif region . start < start and region . end > end : <EOL> if not region in buf : <EOL> yield region <EOL> buf . add ( region ) <EOL> def tell ( self ) : <EOL> return self . _tellpos <EOL> def close ( self ) : <EOL> pass <EOL> @ property <EOL> def length ( self ) : <EOL> return self . _length <EOL> @ property <EOL> def total ( self ) : <EOL> return self . _total <EOL> def __iter__ ( self ) : <EOL> self . _cur_bin_idx = <NUM_LIT:0> <EOL> self . _cur_bin_pos = <NUM_LIT:0> <EOL> self . _tellpos = <NUM_LIT:0> <EOL> return self <EOL> def next ( self ) : <EOL> if self . _cur_bin_idx >= len ( self . _bin_list ) : <EOL> raise StopIteration <EOL> binvals = self . _bins [ self . _bin_list [ self . _cur_bin_idx ] ] <EOL> while self . _cur_bin_pos < len ( binvals ) : <EOL> val = binvals [ self . _cur_bin_pos ] <EOL> self . _cur_bin_pos += <NUM_LIT:1> <EOL> startbin = ( val . chrom , val . start / BedFile . _bin_const ) <EOL> if startbin == self . _bin_list [ self . _cur_bin_idx ] : <EOL> self . _tellpos += <NUM_LIT:1> <EOL> return val <EOL> self . _cur_bin_idx += <NUM_LIT:1> <EOL> self . _cur_bin_pos = <NUM_LIT:0> <EOL> return self . next ( ) <EOL> class BedRegion ( object ) : <EOL> def __init__ ( self , chrom , start , end , name = '<STR_LIT>' , score = '<STR_LIT>' , strand = '<STR_LIT>' , thickStart = '<STR_LIT>' , thickEnd = '<STR_LIT>' , rgb = '<STR_LIT>' , * args ) : <EOL> self . chrom = chrom <EOL> self . start = int ( start ) <EOL> self . end = int ( end ) <EOL> self . name = name <EOL> if score == '<STR_LIT>' : <EOL> self . score = <NUM_LIT:0> <EOL> else : <EOL> self . score = float ( score ) <EOL> if strand == '<STR_LIT>' : <EOL> self . strand = None <EOL> else : <EOL> self . strand = strand <EOL> if thickStart == '<STR_LIT>' : <EOL> self . thickStart = None <EOL> else : <EOL> self . thickStart = thickStart <EOL> if thickEnd == '<STR_LIT>' : <EOL> self . thickEnd = None <EOL> else : <EOL> self . thickEnd = thickEnd <EOL> if rgb == '<STR_LIT>' : <EOL> self . rgb = None <EOL> else : <EOL> self . rgb = rgb <EOL> self . extras = args <EOL> def clone ( self , chrom = None , start = None , end = None , name = None , score = None , strand = None , thickStart = None , thickEnd = None , rgb = None , * args ) : <EOL> cols = [ ] <EOL> cols . append ( self . chrom if chrom is None else chrom ) <EOL> cols . append ( self . start if start is None else start ) <EOL> cols . append ( self . end if end is None else end ) <EOL> cols . append ( self . name if name is None else name ) <EOL> cols . append ( self . score if score is None else score ) <EOL> cols . append ( self . strand if strand is None else strand ) <EOL> cols . append ( self . thickStart if thickStart is None else thickStart ) <EOL> cols . append ( self . thickEnd if thickEnd is None else thickEnd ) <EOL> cols . append ( self . rgb if rgb is None else rgb ) <EOL> for i , val in enumerate ( self . extras ) : <EOL> if len ( args ) > i : <EOL> cols . append ( args [ i ] ) <EOL> else : <EOL> cols . append ( val ) <EOL> return BedRegion ( * cols ) <EOL> @ property <EOL> def score_int ( self ) : <EOL> score = str ( self . score ) <EOL> if score [ - <NUM_LIT:2> : ] == '<STR_LIT>' : <EOL> score = score [ : - <NUM_LIT:2> ] <EOL> return score <EOL> def __key ( self ) : <EOL> return ( self . chrom , self . start , self . end , self . strand , self . name ) <EOL> def __lt__ ( self , other ) : <EOL> return self . __key ( ) < other . __key ( ) <EOL> def __gt__ ( self , other ) : <EOL> return self . __key ( ) > other . __key ( ) <EOL> def __eq__ ( self , other ) : <EOL> return self . __key ( ) == other . __key ( ) <EOL> def write ( self , out ) : <EOL> out . write ( '<STR_LIT>' % self ) <EOL> def __repr__ ( self ) : <EOL> outcols = [ ] <EOL> if self . rgb : <EOL> outcols . append ( self . rgb ) <EOL> if self . thickEnd or outcols : <EOL> outcols . append ( self . thickEnd if self . thickEnd else self . end ) <EOL> if self . thickStart or outcols : <EOL> outcols . append ( self . thickStart if self . thickStart else self . start ) <EOL> if self . strand or outcols : <EOL> outcols . append ( self . strand ) <EOL> if self . score_int != '<STR_LIT>' or outcols : <EOL> outcols . append ( self . score_int ) <EOL> if self . name or outcols : <EOL> outcols . append ( self . name ) <EOL> outcols . append ( self . end ) <EOL> outcols . append ( self . start ) <EOL> outcols . append ( self . chrom ) <EOL> return '<STR_LIT:\t>' . join ( [ str ( x ) for x in outcols [ : : - <NUM_LIT:1> ] ] ) </s>
