class RulerTrack (Track): """Track for displaying a base-pair ruler along the genome""" def __init__(self, top=2.0, bottom=0.0, minicolor=color(.8,.8,.8), maincolor = color(0,0,0), align=None, text_align="middle", text_color=color(0, 0, 0), show=True, fixed_height=True, **options): Track.__init__(self, **options) self.top = top self.bottom = bottom self.minicolor = minicolor self.maincolor = maincolor self.text_align = text_align self.text_color = text_color self.show = show self.shown = show self.fixed_height = fixed_height if align != None: self.coords = alignlib.CoordConverter(align) else: self.coords = None self.multiscale = Multiscale(marginx=.5, marginy=.5, scalex=10, scaley=10) def draw(self): self.multiscale.init(self.get_window()) self.start = self.view.start-1 self.end = self.view.end self.height = self.top self.multiscale.reset() self.gid = group() return group(self.gid) def update(self): self.win = self.get_window() if not self.show: if self.shown: self.gid = self.win.replace_group(self.gid, group()) self.shown = False else: self.shown = True if not self.multiscale.same_view(): if self.coords == None: g = self.draw_ruler(self.pos, self.start, self.end) else: g = self.draw_align_ruler(self.pos, self.start, self.end) self.gid = self.win.replace_group(self.gid, g) def set_visible(self, visible): self.show = visible def draw_ruler(self, pos, start, end): worldx1, worldy1, worldx2, worldy2 = self.win.get_visible() screenwidth, screenheight = self.win.get_size() worldwidth = worldx2 - worldx1 worldx1 -= worldwidth / 2.0 worldx2 += worldwidth / 2.0 # find appropriate unit if one is not given unit = visual.getRulerAutoSize(screenwidth, worldwidth) order = int(math.log10(unit)) unit2, unitstr = visual.getUnitSuffix(unit) x, y = pos vis = [] # make mini hashes if unit >= 10: vis.append(self.minicolor) i = unit * (max(start, worldx1 - x + start) // unit) while x + i - start <= worldx2 and i < end: if i >= start: vis.append(lines(x + i - start, y+self.bottom, x + i - start, y+self.top)) i += unit // 10 # make main hashes i = unit * (max(start, worldx1 - x + start) // unit) while x + i - start <= worldx2 and i < end: if i >= start: vis.append(self.maincolor) vis.append(lines(x + i - start, y, x + i - start, y + self.top)) vis.append(self.text_color) vis.append(text(str(int(i//unit2)) + unitstr, x + i - start, y, x + i -start - unit, y + self.top, self.text_align, "right")) i += unit # base line vis.append(lines(self.maincolor, x, y, x + end - start, y)) return group(* vis) def draw_align_ruler(self, pos, start, end): worldx1, worldy1, worldx2, worldy2 = self.win.get_visible() screenwidth, screenheight = self.win.get_size() worldwidth = worldx2 - worldx1 worldx1 -= worldwidth / 2.0 worldx2 += worldwidth / 2.0 # find appropriate unit if one is not given unit = visual.getRulerAutoSize(screenwidth, worldwidth) order = int(math.log10(unit)) unit2, unitstr = visual.getUnitSuffix(unit) x, y = pos vis = [] # make mini hashes vis.append(self.minicolor) i = unit * (max(start, worldx1 - x + start) // unit) while x + i - start <= worldx2 and i < end: if i >= start: vis.append(lines(x + i - start, y + self.bottom, x + i - start, y + self.height)) i += max(unit // 10, 1) # make main hashes # find starting local coord seqi = unit * ((start + self.coords.align2local(max(0, worldx1 - x), clamp=True)) // unit) \ - start-1 # find starting align coord i = self.coords.local2align(seqi) endseqi = min(self.coords.align2local(end, clamp=True), self.coords.align2local(worldx2-x, clamp=True)) # draw all hashes in view while seqi <= endseqi: vis.append(self.maincolor) vis.append(lines(x + i+1, y, x + i+1, y + self.height)) vis.append(self.text_color) vis.append(text(str(int((seqi+start+1)//unit2)) + unitstr, x + i+1, y, x + i+1 - unit, y + self.height, self.text_align, "right")) seqi += unit i = self.coords.local2align(seqi, clamp=True) # base line vis.append(lines(self.maincolor, x, y, x + end - start, y)) return group(* vis)
class RulerTrack(Track): """Track for displaying a base-pair ruler along the genome""" def __init__(self, top=2.0, bottom=0.0, minicolor=color(.8, .8, .8), maincolor=color(0, 0, 0), align=None, text_align="middle", text_color=color(0, 0, 0), show=True, fixed_height=True, **options): Track.__init__(self, **options) self.top = top self.bottom = bottom self.minicolor = minicolor self.maincolor = maincolor self.text_align = text_align self.text_color = text_color self.show = show self.shown = show self.fixed_height = fixed_height if align != None: self.coords = alignlib.CoordConverter(align) else: self.coords = None self.multiscale = Multiscale(marginx=.5, marginy=.5, scalex=10, scaley=10) def draw(self): self.multiscale.init(self.get_window()) self.start = self.view.start - 1 self.end = self.view.end self.height = self.top self.multiscale.reset() self.gid = group() return group(self.gid) def update(self): self.win = self.get_window() if not self.show: if self.shown: self.gid = self.win.replace_group(self.gid, group()) self.shown = False else: self.shown = True if not self.multiscale.same_view(): if self.coords == None: g = self.draw_ruler(self.pos, self.start, self.end) else: g = self.draw_align_ruler(self.pos, self.start, self.end) self.gid = self.win.replace_group(self.gid, g) def set_visible(self, visible): self.show = visible def draw_ruler(self, pos, start, end): worldx1, worldy1, worldx2, worldy2 = self.win.get_visible() screenwidth, screenheight = self.win.get_size() worldwidth = worldx2 - worldx1 worldx1 -= worldwidth / 2.0 worldx2 += worldwidth / 2.0 # find appropriate unit if one is not given unit = visual.getRulerAutoSize(screenwidth, worldwidth) order = int(math.log10(unit)) unit2, unitstr = visual.getUnitSuffix(unit) x, y = pos vis = [] # make mini hashes if unit >= 10: vis.append(self.minicolor) i = unit * (max(start, worldx1 - x + start) // unit) while x + i - start <= worldx2 and i < end: if i >= start: vis.append( lines(x + i - start, y + self.bottom, x + i - start, y + self.top)) i += unit // 10 # make main hashes i = unit * (max(start, worldx1 - x + start) // unit) while x + i - start <= worldx2 and i < end: if i >= start: vis.append(self.maincolor) vis.append(lines(x + i - start, y, x + i - start, y + self.top)) vis.append(self.text_color) vis.append( text( str(int(i // unit2)) + unitstr, x + i - start, y, x + i - start - unit, y + self.top, self.text_align, "right")) i += unit # base line vis.append(lines(self.maincolor, x, y, x + end - start, y)) return group(*vis) def draw_align_ruler(self, pos, start, end): worldx1, worldy1, worldx2, worldy2 = self.win.get_visible() screenwidth, screenheight = self.win.get_size() worldwidth = worldx2 - worldx1 worldx1 -= worldwidth / 2.0 worldx2 += worldwidth / 2.0 # find appropriate unit if one is not given unit = visual.getRulerAutoSize(screenwidth, worldwidth) order = int(math.log10(unit)) unit2, unitstr = visual.getUnitSuffix(unit) x, y = pos vis = [] # make mini hashes vis.append(self.minicolor) i = unit * (max(start, worldx1 - x + start) // unit) while x + i - start <= worldx2 and i < end: if i >= start: vis.append( lines(x + i - start, y + self.bottom, x + i - start, y + self.height)) i += max(unit // 10, 1) # make main hashes # find starting local coord seqi = unit * ((start + self.coords.align2local(max(0, worldx1 - x), clamp=True)) // unit) \ - start-1 # find starting align coord i = self.coords.local2align(seqi) endseqi = min(self.coords.align2local(end, clamp=True), self.coords.align2local(worldx2 - x, clamp=True)) # draw all hashes in view while seqi <= endseqi: vis.append(self.maincolor) vis.append(lines(x + i + 1, y, x + i + 1, y + self.height)) vis.append(self.text_color) vis.append( text( str(int((seqi + start + 1) // unit2)) + unitstr, x + i + 1, y, x + i + 1 - unit, y + self.height, self.text_align, "right")) seqi += unit i = self.coords.local2align(seqi, clamp=True) # base line vis.append(lines(self.maincolor, x, y, x + end - start, y)) return group(*vis)