def drawFeatures(self): # print("DO output path feature") # only resize the canvas if software is loaded. This prevents error messages # draw the helper plain white circle to make selection possible: self.ctx.arc(0,0,self.radiusO+1,0,2*math.pi) # outer circle self.ctx.set_source_rgb (1, 1, 1) # white self.ctx.set_line_width (0) # no line self.plasmidstore.interaction["markerArea1"] = self.ctx.copy_path() # copy for later self.ctx.new_path() # remove self.ctx.arc(0,0,self.radiusI-1,0,2*math.pi) # inner circle self.ctx.set_source_rgb (1,1,1) # Solid white self.ctx.set_line_width (0) # no line self.plasmidstore.interaction["markerArea2"] = self.ctx.copy_path() # copy for later self.ctx.new_path() # remove # draw the plasmid (two circles with different radius) radius=10 self.ctx.arc(0,0,self.radiusO,0, 2*math.pi) # circle self.ctx.set_source_rgb (0, 0, 0) # Solid color self.ctx.set_line_width (0.24) # line width self.ctx.stroke() # stroke only no fill! # inner plasmid self.ctx.arc(0,0,self.radiusI,0,2*math.pi) # inner circle self.ctx.stroke() # stroke the same color and settings # draw the buffered featrues: i = 0 for a in self.plasmidstore.drawnfeatures: path = self.plasmidstore.drawnfeatures[a][0] # get color featuretype = self.plasmidstore.drawnfeatures[a][1] color = eval(featuretype)['fw'] #get the color of feature (as string) assert type(color) == str r,g,b = colcol.hex_to_rgb(color) r = float(r)/255 g = float(g)/255 b = float(b)/255 # put the path on the canvas and fill #self.ctx.new_path() self.ctx.append_path(path) self.ctx.set_source_rgba (r,g,b,1.0) # Solid color self.ctx.fill_preserve() # outline for the feature that is beneeth the mouse: if a == self.Highlight: #self.ctx.set_source_rgb (1, 0, 0) self.ctx.set_line_width(0.3) self.ctx.stroke() else: # remove path self.ctx.new_path() i = i + 1 return None
def update_ownUI(self): ''' Refreshes only the UI of this panel by re-filling the table from features stored in the genbank object ''' #need to figure out how to do this without changing the selection.... self.feature_list.DeleteAllItems() item = 0 #for feautrecolor features = genbank.gb.get_all_features() if features != None: for entry in features: # print(entry) if len(entry['qualifiers']) == 0: col0 = entry['key'] else: col0 = entry['qualifiers'][0].split('=')[1] col1 = entry['key'] locationstring = '' for location in entry['location']: if locationstring != '': locationstring += ', ' locationstring += str(location) col2 = locationstring if entry['complement'] == True: col3 = 'complement' else: col3 = 'leading' # col4 = entry['qualifiers'] self.feature_list.Append([col0, col1, col2, col3]) #coloring self.get_feature_color(entry) hexcolor = self.current_highlight_color #get hex color r, g, b = colcol.hex_to_rgb(hexcolor) #convert to RGB color = wx.Colour(r, g, b) #make color object self.feature_list.SetItemBackgroundColour(item, color) item += 1 try: if genbank.feature_selection != None: #focus on the selected feature self.focus_feature_selection() except: pass
def drawSelection(self): ''' draw arc for selection ''' if self.plasmidstore.drawnSelection != None: #0082ED r,g,b = colcol.hex_to_rgb('#0082ED') r = float(r)/255 g = float(g) /255 b = float(b) /255 self.ctx.set_source_rgba (r,g,b, 0.6) # Solid color self.ctx.set_line_width(3) path = self.plasmidstore.drawnSelection self.ctx.append_path(path) self.ctx.stroke() if self.plasmidstore.drawnSelection == None and self.plasmidstore.drawnPosition != None: self.ctx.set_source_rgba (0,0,0) # Solid color self.ctx.set_line_width(0.2) path = self.plasmidstore.drawnPosition self.ctx.append_path(path) self.ctx.stroke()
def drawFeatures(self): features = genbank.gb.get_all_feature_positions() paths = {} # (color, path) featureheight = 10 if self.cairoStorage['features'] != features : # something changed, we have to draw the paths new self.drawn_fw_locations = [] self.drawn_rv_locations = [] # font settings # draw the name somewhere at the start nameheight = 9 # px self.ctx.select_font_face('Arial', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) self.ctx.set_font_size(nameheight) for feature in features: featuretype, complement, start, finish, name, index = feature if featuretype != "source": # get names hname = self.hitName(name, index) name = self.nameBeautiful(name) #get position xs, ys, ws, hs = self.senseLayout.index_to_pos(start) xf, yf, wf, hf = self.senseLayout.index_to_pos(finish+1) # linecount: # if ys and yf are not the same, we have feature over multiple lines! dy = abs(ys - yf) / pango.SCALE ySteps = dy / self.lineHeight # number of lines! xs = xs / pango.SCALE xf = xf / pango.SCALE ys = (ys / pango.SCALE) + self.sY yf = yf / pango.SCALE # first sense strain over the text if complement == False: self.drawn_fw_locations, l = self.find_overlap(self.drawn_fw_locations, (start, finish)) level = l * (featureheight+6) xbearing, ybearing, TextWidth, TextHeight, xadvance, yadvance = self.ctx.text_extents(name) ys = ys - level - 5 self.ctx.move_to(xs + 10, ys ) self.ctx.text_path(name) textpath = self.ctx.copy_path() self.ctx.new_path() # end name # box for name self.ctx.move_to(xs, ys) self.ctx.rectangle(xs, ys-featureheight, TextWidth + 20 , nameheight + 5) # lines above the dna while ySteps >= 0: if ySteps == 0: xE = xf else: xE = self.w + 5 # TODO: figure out, why we need to add 5 px, to make it look correct # make a box-path self.ctx.move_to(xs, ys) self.ctx.rectangle(xs, ys-5, xE-xs , 5) # the second x start is always 8px, or what we will opt for xs = self.dX ys = ys + self.lineHeight ySteps = ySteps - 1 # path fillpath = self.ctx.copy_path() self.ctx.new_path() # get color color = eval(featuretype)['fw'] #get the color of feature (as string) else: self.drawn_rv_locations, l = self.find_overlap(self.drawn_rv_locations, (start, finish)) level = l * (featureheight+6) # set y ys = ys + 2*self.fontsize + self.lineGap + 9 + level # lines below the dna while ySteps >= 0: if ySteps == 0: xE = xf else: xE = self.w # make the path #self.ctx.move_to(xs, ys) #self.ctx.line_to(xE, ys) self.ctx.move_to(xs, ys) self.ctx.rectangle(xs, ys+5, xE-xs , 5) xs = self.dX ys = ys + self.lineHeight ySteps = ySteps - 1 # change y: ys = ys - self.lineHeight # buffer path bufferPath = self.ctx.copy_path() self.ctx.new_path() # name at the end: xbearing, ybearing, TextWidth, TextHeight, xadvance, yadvance = self.ctx.text_extents(name) self.ctx.move_to(xf - TextWidth - 10, ys + 10 ) self.ctx.text_path(name) textpath = self.ctx.copy_path() self.ctx.new_path() # end name # box for name self.ctx.append_path(bufferPath) self.ctx.move_to(xf - TextWidth, ys + featureheight) self.ctx.rectangle(xf - TextWidth - 20, ys, TextWidth + 20 , nameheight + 5) # get path fillpath = self.ctx.copy_path() self.ctx.new_path() # get color color = eval(featuretype)['fw'] #get the color of feature (as string) paths[hname] = (color,fillpath ,textpath) self.ctx.new_path() # clear canvas # save the paths self.cairoStorage['fPaths'] = paths # update storage status self.cairoStorage['features'] = features # draw the beautiful features for a in self.cairoStorage['fPaths']: color, path, tpath = self.cairoStorage['fPaths'][a] # get color assert type(color) == str r,g,b = colcol.hex_to_rgb(color) r = float(r)/255 g = float(g)/255 b = float(b)/255 # append and draw path self.ctx.append_path(path) self.ctx.set_line_width(1) self.ctx.set_source_rgba(r ,g ,b , 1) # Solid color #self.ctx.stroke_preserve() self.ctx.fill() # write text self.ctx.append_path(tpath) self.ctx.set_line_width(1) self.ctx.set_source_rgba(1 ,1 ,1 , 1) # Solid color self.ctx.fill() return None
def drawFeatures(self): features = genbank.gb.get_all_feature_positions() paths = {} # (color, path) featureheight = 10 if self.cairoStorage['features'] != features: # something changed, we have to draw the paths new self.drawn_fw_locations = [] self.drawn_rv_locations = [] # font settings # draw the name somewhere at the start nameheight = 9 # px self.ctx.select_font_face('Arial', cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL) self.ctx.set_font_size(nameheight) for feature in features: featuretype, complement, start, finish, name, index = feature if featuretype != "source": # get names hname = self.hitName(name, index) name = self.nameBeautiful(name) #get position xs, ys, ws, hs = self.senseLayout.index_to_pos(start) xf, yf, wf, hf = self.senseLayout.index_to_pos(finish + 1) # linecount: # if ys and yf are not the same, we have feature over multiple lines! dy = abs(ys - yf) / pango.SCALE ySteps = dy / self.lineHeight # number of lines! xs = xs / pango.SCALE xf = xf / pango.SCALE ys = (ys / pango.SCALE) + self.sY yf = yf / pango.SCALE # first sense strain over the text if complement == False: self.drawn_fw_locations, l = self.find_overlap( self.drawn_fw_locations, (start, finish)) level = l * (featureheight + 6) xbearing, ybearing, TextWidth, TextHeight, xadvance, yadvance = self.ctx.text_extents( name) ys = ys - level - 5 self.ctx.move_to(xs + 10, ys) self.ctx.text_path(name) textpath = self.ctx.copy_path() self.ctx.new_path() # end name # box for name self.ctx.move_to(xs, ys) self.ctx.rectangle(xs, ys - featureheight, TextWidth + 20, nameheight + 5) # lines above the dna while ySteps >= 0: if ySteps == 0: xE = xf else: xE = self.w + 5 # TODO: figure out, why we need to add 5 px, to make it look correct # make a box-path self.ctx.move_to(xs, ys) self.ctx.rectangle(xs, ys - 5, xE - xs, 5) # the second x start is always 8px, or what we will opt for xs = self.dX ys = ys + self.lineHeight ySteps = ySteps - 1 # path fillpath = self.ctx.copy_path() self.ctx.new_path() # get color color = eval(featuretype)[ 'fw'] #get the color of feature (as string) else: self.drawn_rv_locations, l = self.find_overlap( self.drawn_rv_locations, (start, finish)) level = l * (featureheight + 6) # set y ys = ys + 2 * self.fontsize + self.lineGap + 9 + level # lines below the dna while ySteps >= 0: if ySteps == 0: xE = xf else: xE = self.w # make the path #self.ctx.move_to(xs, ys) #self.ctx.line_to(xE, ys) self.ctx.move_to(xs, ys) self.ctx.rectangle(xs, ys + 5, xE - xs, 5) xs = self.dX ys = ys + self.lineHeight ySteps = ySteps - 1 # change y: ys = ys - self.lineHeight # buffer path bufferPath = self.ctx.copy_path() self.ctx.new_path() # name at the end: xbearing, ybearing, TextWidth, TextHeight, xadvance, yadvance = self.ctx.text_extents( name) self.ctx.move_to(xf - TextWidth - 10, ys + 10) self.ctx.text_path(name) textpath = self.ctx.copy_path() self.ctx.new_path() # end name # box for name self.ctx.append_path(bufferPath) self.ctx.move_to(xf - TextWidth, ys + featureheight) self.ctx.rectangle(xf - TextWidth - 20, ys, TextWidth + 20, nameheight + 5) # get path fillpath = self.ctx.copy_path() self.ctx.new_path() # get color color = eval(featuretype)[ 'fw'] #get the color of feature (as string) paths[hname] = (color, fillpath, textpath) self.ctx.new_path() # clear canvas # save the paths self.cairoStorage['fPaths'] = paths # update storage status self.cairoStorage['features'] = features # draw the beautiful features for a in self.cairoStorage['fPaths']: color, path, tpath = self.cairoStorage['fPaths'][a] # get color assert type(color) == str r, g, b = colcol.hex_to_rgb(color) r = float(r) / 255 g = float(g) / 255 b = float(b) / 255 # append and draw path self.ctx.append_path(path) self.ctx.set_line_width(1) self.ctx.set_source_rgba(r, g, b, 1) # Solid color #self.ctx.stroke_preserve() self.ctx.fill() # write text self.ctx.append_path(tpath) self.ctx.set_line_width(1) self.ctx.set_source_rgba(1, 1, 1, 1) # Solid color self.ctx.fill() return None
def drawCairoArrow(self, feature, hittestName, radius, radius_change, lev,arrow_head_length, length, degreeMult, bw, bc, high ): '''Function to draw the arrow onto the canvas and save its path for a hittest''' # load infos: featuretype, complement, start, finish, name, index = feature # draw if complement == False: self.drawn_fw_locations, levelMult = self.find_overlap(self.drawn_fw_locations, (start, finish)) if levelMult>3 or finish-start<=5: #Only allow for tree levels. Also, for very short features, draw them at bottom level levelMult = 0 radius_change = radius_change * 1.25 level = lev * (1+levelMult) s_deg = float(start) * degreeMult # in degree f_deg = float(finish) * degreeMult s_rad = (s_deg * math.pi/180) - math.pi/2 f_rad = (f_deg * math.pi/180) - math.pi/2 f_rad_wo_head = ((f_deg-arrow_head_length) * math.pi/180) - math.pi/2 f_rad_wo_head_help = ((f_deg-2*arrow_head_length) * math.pi/180) - math.pi/2 # weather to draw a head or not, only if feature is large enough drawHead = True if f_rad_wo_head_help < s_rad: f_rad_wo_head = f_rad drawHead = False arrow_head_x, arrow_head_y = self.radial2cartesian(radius+level, f_rad) arrow_head_x1, arrow_head_y1 = self.radial2cartesian(radius+level+radius_change+0.5, f_rad_wo_head) arrow_head_x2, arrow_head_y2 = self.radial2cartesian(radius+level-radius_change-0.5, f_rad_wo_head) # get the color: color = eval(featuretype)['fw'] #get the color of feature (as string) assert type(color) == str # move to start x_start, y_start = self.radial2cartesian(radius+level+radius_change, s_rad) self.ctx.move_to(x_start, y_start) self.labelHelper[hittestName].append(radius+level-radius_change) # inner radius self.labelHelper[hittestName].append(radius+level+radius_change) # outer radius # the actual drawing: self.ctx.arc(0, 0, radius+level+radius_change,s_rad, f_rad_wo_head); if drawHead: self.ctx.line_to(arrow_head_x1,arrow_head_y1) self.ctx.line_to(arrow_head_x,arrow_head_y) self.ctx.line_to(arrow_head_x2,arrow_head_y2) self.ctx.arc_negative(0, 0, radius+level-radius_change, f_rad_wo_head, s_rad); self.ctx.close_path () else: self.drawn_rv_locations, levelMult = self.find_overlap(self.drawn_rv_locations, (start, finish)) if levelMult>3 or finish-start<=5: #Only allow for tree levels. Also, for very short features, draw them at bottom level levelMult = 0 radius_change = radius_change * 1.25 # for bigger items! level = lev * (1+levelMult) s_deg = float(finish) * degreeMult # in degree f_deg = float(start) * degreeMult s_rad = (s_deg * math.pi/180) - math.pi/2 f_rad = (f_deg * math.pi/180) - math.pi/2 f_rad_wo_head = ((f_deg + arrow_head_length) * math.pi/180) - math.pi/2 f_rad_wo_head_help = ((f_deg + 1.5 * arrow_head_length) * math.pi/180) - math.pi/2 # weather to draw a head or not, only if feature is large enough drawHead = True if f_rad_wo_head_help > s_rad: f_rad_wo_head = f_rad drawHead = False arrow_head_x, arrow_head_y = self.radial2cartesian(radius-level, f_rad) arrow_head_x1, arrow_head_y1 = self.radial2cartesian(radius-level-radius_change-0.5, f_rad_wo_head) arrow_head_x2, arrow_head_y2 = self.radial2cartesian(radius-level+radius_change+0.5, f_rad_wo_head) # get the color: color = eval(featuretype)['rv'] #get the color of feature (as string) assert type(color) == str # move to start x_start, y_start = self.radial2cartesian(radius-level-radius_change, s_rad) self.ctx.move_to(x_start, y_start) self.labelHelper[hittestName].append(radius-level-radius_change) # smallest radius self.labelHelper[hittestName].append(radius-level+radius_change) # outer radius # the actual drawing: self.ctx.arc_negative(0, 0, radius-level-radius_change,s_rad, f_rad_wo_head); if drawHead: self.ctx.line_to(arrow_head_x1,arrow_head_y1) self.ctx.line_to(arrow_head_x,arrow_head_y) self.ctx.line_to(arrow_head_x2,arrow_head_y2) self.ctx.arc(0, 0, radius-level+radius_change, f_rad_wo_head, s_rad); self.ctx.close_path () # now draw the arrows with color and lines r,g,b = colcol.hex_to_rgb(color) r = float(r)/255 g = float(g)/255 b = float(b)/255 self.ctx.set_source_rgba (r,g,b,1.0) # Solid color self.ctx.set_line_width (bw) # or 0.1 self.ctx.fill_preserve () self.ctx.set_source_rgb (bc[0],bc[1],bc[2]) # save feature to hittest: self.hitpath = self.ctx.copy_path() self.hittest[hittestName].append(self.hitpath) self.ctx.stroke() # return the path if it should be highlighted! if high == True: return self.hitpath, color else: return False, False
def drawCairoFeatures(self): '''Loops trough features and calls other functions to draw the arrows and the labels''' # set some variables featurelist = genbank.gb.get_all_feature_positions() self.drawn_fw_locations = [] # for location tracing foreward self.drawn_rv_locations = [] # for location tracing reverse drawHightlight = False highPath = [] highColor = [] ##################### # Settings loaded from self.opt radius = self.opt.pRadius arrow_thickness = self.opt.pArrowThick # like everything in percent radius_change = self.opt.pRadChange # initial space between arrow and plasmid lev = self.opt.pLevAdd # level distance arrow_head_length = self.opt.pArrowHeadLength length = float(len(genbank.gb.GetDNA())) degreeMult = float(360/length) bordercolor = self.opt.pFeatureBC borderwidth = self.opt.pBW bordercolorHigh = self.opt.pFeatureBChigh borderwidthHigh = self.opt.pBWhigh ##################### # loop through all features for i in range(0,len(featurelist)): # load all the feature infos featuretype, complement, start, finish, name, index = featurelist[i] feature = featurelist[i] # variable to save as a hittest hittestName = "%s%s" % (name, index) # name and index as indicator! self.hittest[hittestName] = [] # initialise list to store arrow and label of a feature as paths self.labelHelper[hittestName] = [True] # save radius of arrow to draw the label maybe # highlitght this element? if self.Highlight == hittestName or self.HighlightClick == hittestName: drawHightlight = True passBC = bordercolorHigh # border Color else: passBC = bordercolor # border Color drawHightlight = False # draw the arrow: arrowResult, arrowResult2 = self.drawCairoArrow(feature, hittestName, radius, radius_change, lev,arrow_head_length, length, degreeMult, borderwidth, passBC, drawHightlight ) # if we want to highlight this if arrowResult != False: # we get color and the path from the function to save! highPath.append(arrowResult) highColor.append(arrowResult2) # now draw the highlitgh arrow, so its on top: # it is then drawn twice at the same position! if len(highPath) >0: i = 0 for path, color in zip(highPath, highColor): self.ctx.append_path(path) r,g,b = colcol.hex_to_rgb(color) r = float(r)/255 g = float(g)/255 b = float(b)/255 self.ctx.set_source_rgb (r,g,b,) # Solid color self.ctx.set_line_width (borderwidthHigh) # or 0.1 self.ctx.fill_preserve () self.ctx.set_source_rgb (bordercolorHigh[0],bordercolorHigh[1],bordercolorHigh[2]) self.ctx.stroke() # loop through all features to draw the labels in arrows! for i in range(0,len(featurelist)): # load all the feature infos featuretype, complement, start, finish, name, index = featurelist[i] feature = featurelist[i] # variable to save as a hittest hittestName = "%s%s" % (name, index) # random pattern # draw the label and the line connecting them labelresult = self.drawArrowLabels(feature, hittestName) if labelresult != False: # this label was not drawn into arrow # save it hittest name as missing self.labelHelper[hittestName] = [False,feature] # here draw the other Labels: self.drawCairoLabels() return True