File size: 2,303 Bytes
b4bd946
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import drawsvg as draw
import numpy as np

def draw_line(d,x1,y1,x2,y2,color):
    d.append(draw.Lines(x1,y1,
            x2,y2,
            close=False,
            fill="none",
            stroke=color,
            stroke_width=2))


def draw_nucleotide(d,x, y, nt, color):
    """ Draw one nucleotide in a circle
    """
    assert(len(nt)==1)
    
    d.append(draw.Circle(x, y, 8,
        fill=color, stroke_width=2, stroke='black'))
    deltax = 4.3 if nt=="A" else (4.5 if nt=="U" else 4.7)
    d.append(draw.Text(nt, 11, x-deltax, y+4, fill="black", font_weight="bold"))  # use 11pt text 
    
def draw_oligo(d,xs, ys, nts, colors):
    lastx = None
    lasty = None
    
    for (x,y,nt,color) in zip(xs,ys,nts,colors): # first draw all the black lines connecting the nucleotides
        if lastx != None:
            draw_line(d,lastx,lasty,x,y,"black")
        lastx, lasty = x,y

    for (x,y,nt,color) in zip(xs,ys,nts,colors):
        draw_nucleotide(d,x,y,nt,color)

        
BASE_PAIR_COLOR = "#ff4e4e"
DELTA_X = 20
DELTA_Y = 20
LOOP_RADIUS_PER_LOOP_LENGTH = {3:18, 4:20, 5:23,6:26}

def draw_stem_loop(nts, stem_length, colors, filename):
    """ First nucleotide is just upstream of stem; then stem; then loop; then 3' part of stem; then another nucleotide outside stem
    """
    assert(len(nts)==len(colors))
    
    d = draw.Drawing(500, 200, origin='center')
       
    for i in range(stem_length):
        draw_line(d,i*DELTA_X,0,i*DELTA_X,DELTA_Y,BASE_PAIR_COLOR)
    
    loop_length = len(nts) - 2*stem_length - 2   
    assert((loop_length >= 3) and (loop_length <= 6))
    loop_radius = LOOP_RADIUS_PER_LOOP_LENGTH[loop_length]

    
    xs = [-0.7*DELTA_X,] + [DELTA_X * i for i in range(stem_length)] + [DELTA_X * (stem_length-1) + loop_radius* np.cos(2*np.pi*(1/2)/(loop_length+2)) - loop_radius * np.cos(2*np.pi*(i+3/2)/(loop_length+2)) for i in range(loop_length)] + [DELTA_X * (stem_length-1-i) for i in range(stem_length)] + [-0.7*DELTA_X]
    ys = [-0.7*DELTA_Y,] + [0] * stem_length + [DELTA_Y/2 - loop_radius * np.sin(2*np.pi*(i+3/2)/(loop_length+2)) for i in range(loop_length)] + [DELTA_Y]*stem_length + [1.7*DELTA_Y]
    
    draw_oligo(d,xs,ys,nts,colors)
    
    d.set_pixel_scale(2)  # Set number of pixels per geometry unit
    d.save_svg(filename)