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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
| def foo(seq,struct):
out = []
ln = len(seq)
matches = [[[-1, ln, 0, 0]]]
grp_idx = 0
idx = 0
closing = False
out_grp = False
# Let's first parse that dummy struct string into lists of groups.
for i, el in enumerate(struct):
if el == '(':
if out_grp:
matches[grp_idx][0][1] = i
grp_idx += 1
out_grp = False
idx += 1
matches[grp_idx].append([i, ln, 0, 0])
elif el == ')':
closing = True
matches[grp_idx][idx][1] = i
idx -= 1
if idx == 0:
matches.append([[i, ln, 0, 0]]) # Add a new group.
out_grp = True # To force creation of a new group.
closing = False
elif el == '.':
if out_grp:
matches[grp_idx][idx][3] += 1
matches[grp_idx+1][idx][2] += 1
elif closing:
matches[grp_idx][idx][3] += 1
else:
matches[grp_idx][idx][2] += 1
# Now that all matches have been parsed, create their char representation.
for grp_idx, grp in enumerate(matches):
out.append([])
if len(grp) == 0:
continue
# If only one element in grp (hence no matching bases).
elif len(grp) == 1:
print grp
m = grp[0]
# Here, m[3] will always be 0.
if m[2] == 1: # Only one base.
out[grp_idx].append((" ", " ", seq[m[0]+1], " ", " "))
elif m[2] > 1:
nr = m[2]/2.0
for i in xrange(1, int(nr)):
out[grp_idx].append((seq[m[0]+i], " ", " ", " ", seq[m[1]-i]))
if int(nr) == nr: # Even number of "ending bases":
out[grp_idx].append((" ", seq[m[0]+i+1], " ", seq[m[1]-i-1], " "))
else:
out[grp_idx].append((" ", seq[m[0]+i+1], " ", seq[m[1]-i-1], " "))
out[grp_idx].append((" ", " ", seq[m[0]+i+2], " ", " "))
continue
# First element of each group is special, as it is not delimited by matching parenthesis.
m = grp[0]
if m[2] > m[3]:
delta = m[2] - m[3]
for i in xrange(1, m[2]+1):
if i - 1 < delta:
out[grp_idx].append((seq[m[0]+i], " ", " ", " ", "-"))
else:
out[grp_idx].append((seq[m[0]+i], " ", " ", " ", seq[m[1]-i+delta]))
else:
delta = m[3] - m[2]
for i in xrange(1, m[3]+1):
if i - 1 < delta:
out[grp_idx].append(("-", " ", " ", " ", seq[m[1]-i]))
else:
out[grp_idx].append((seq[m[0]+i-delta], " ", " ", " ", seq[m[1]-i]))
for m in grp[1:-1]:
out[grp_idx].append((" ", seq[m[0]], "|", seq[m[1]], " "))
if m[2] > m[3]:
delta = m[2] - m[3]
for i in xrange(1, m[2]+1):
if i - 1 < delta:
out[grp_idx].append((seq[m[0]+i], " ", " ", " ", "-"))
else:
out[grp_idx].append((seq[m[0]+i], " ", " ", " ", seq[m[1]-i+delta]))
else:
delta = m[3] - m[2]
for i in xrange(1, m[3]+1):
if i - 1 < m[3] - m[2]:
out[grp_idx].append(("-", " ", " ", " ", seq[m[1]-i]))
else:
out[grp_idx].append((seq[m[0]+i], " ", " ", " ", seq[m[1]-i]))
# Last element in a group is also a special case!
m = grp[-1]
out[grp_idx].append((" ", seq[m[0]], "|", seq[m[1]], " "))
# Here, m[3] will always be 0.
if m[2] == 1: # Only one base.
out[grp_idx].append((" ", " ", seq[m[0]+1], " ", " "))
elif m[2] > 1:
nr = m[2]/2.0
for i in xrange(1, int(nr)):
out[grp_idx].append((seq[m[0]+i], " ", " ", " ", seq[m[1]-i]))
if int(nr) == nr: # Even number of "ending bases":
out[grp_idx].append((" ", seq[m[0]+i+1], " ", seq[m[1]-i-1], " "))
else:
out[grp_idx].append((" ", seq[m[0]+i+1], " ", seq[m[1]-i-1], " "))
out[grp_idx].append((" ", " ", seq[m[0]+i+2], " ", " "))
return '\n\n'.join(['\n'.join([''.join(l) for l in zip(*grp)]) for grp in out])
#seq = "CUGAGGUGAGGUAGUAGGUUGUAUAGUUCAGAAGUACAACAUUGGAGAUGACUGUACAACCCGUUACCUUUUUUUGGGUCAUAUGCGUCGAUCGGUAC"
#struct = "(..(((.(((((((..(((((((((((.((......((....))....)))))))))))))..))))))).)))..).....((.)).(...)....."
seq = "CCAGGCCUGUUAAGCAUAAGUACUUCUUUACUAUCCCAUACUGAACUCAAUUGUAUGGAAUGUAAAGAAGUAUGUAUGGUUAGCAGGCUACCACGU"
struct = "...((((((((((.((((.((((((((((((.((.((((((...........)))))).)))))))))))))).)))).))))))))))......."
print foo(seq,struct) |
Partager