1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include "ViennaRNA/utils/basic.h"
5 #include "ViennaRNA/landscape/move.h"
6
7
8 PUBLIC vrna_move_t
vrna_move_init(int pos_5,int pos_3)9 vrna_move_init(int pos_5,
10 int pos_3)
11 {
12 return (vrna_move_t){
13 pos_5, pos_3, NULL
14 };
15 }
16
17
18 PUBLIC void
vrna_move_list_free(vrna_move_t * moves)19 vrna_move_list_free(vrna_move_t *moves)
20 {
21 if (moves) {
22 for (vrna_move_t *move = moves; move->pos_5 != 0; move++) {
23 if (move->next != NULL)
24 if (move->next->pos_5 != 0)
25 vrna_move_list_free(move->next);
26 }
27 free(moves);
28 }
29 }
30
31
32 PUBLIC void
vrna_move_apply(short * pt,const vrna_move_t * m)33 vrna_move_apply(short *pt,
34 const vrna_move_t *m)
35 {
36 /* deletion */
37 if (vrna_move_is_removal(m)) {
38 pt[-m->pos_5] = 0;
39 pt[-m->pos_3] = 0;
40 } else if (vrna_move_is_insertion(m)) {
41 pt[m->pos_5] = m->pos_3;
42 pt[m->pos_3] = m->pos_5;
43 } else
44 /* shift right */
45 if (m->pos_5 > 0 && m->pos_3 < 0) {
46 short previousPairedPosition = pt[m->pos_5];
47 pt[previousPairedPosition] = 0;
48 short newPairedPosition = -m->pos_3;
49 pt[m->pos_5] = newPairedPosition;
50 pt[newPairedPosition] = m->pos_5;
51 } else
52
53 /* shift left */
54 if (m->pos_5 < 0 && m->pos_3 > 0) {
55 short previousPairedPosition = pt[m->pos_3];
56 pt[previousPairedPosition] = 0;
57 short newPairedPosition = -m->pos_5;
58 pt[m->pos_3] = newPairedPosition;
59 pt[newPairedPosition] = m->pos_3;
60 }
61
62 /* apply successive moves if m.next is a list */
63 if (m->next != NULL)
64 for (vrna_move_t *move = m->next; move->pos_5 != 0; move++)
65 vrna_move_apply(pt, move);
66 }
67
68
69 PUBLIC void
vrna_move_apply_db(char * structure,const short * pt,const vrna_move_t * m)70 vrna_move_apply_db(char *structure,
71 const short *pt,
72 const vrna_move_t *m)
73 {
74 /* deletion */
75 if (vrna_move_is_removal(m)) {
76 structure[-m->pos_5 - 1] = '.';
77 structure[-m->pos_3 - 1] = '.';
78 return;
79 }
80
81 /* insertion */
82 if (vrna_move_is_insertion(m)) {
83 structure[m->pos_5 - 1] = '(';
84 structure[m->pos_3 - 1] = ')';
85 return;
86 }
87
88 /* shift right */
89 if (m->pos_5 > 0) {
90 short previousPairedPosition = pt[m->pos_5];
91 structure[previousPairedPosition - 1] = '.';
92 int left = m->pos_5 - 1;
93 int right = -m->pos_3 - 1;
94 structure[left] = '(';
95 structure[right] = ')';
96 return;
97 }
98
99 /* shift left */
100 if (m->pos_5 < 0) {
101 short previousPairedPosition = pt[m->pos_3];
102 structure[previousPairedPosition - 1] = '.';
103 int left = -m->pos_5 - 1;
104 int right = m->pos_3 - 1;
105 structure[left] = '(';
106 structure[right] = ')';
107 return;
108 }
109 }
110
111
112 PUBLIC int
vrna_move_is_removal(const vrna_move_t * m)113 vrna_move_is_removal(const vrna_move_t *m)
114 {
115 return (m->pos_5 < 0) && (m->pos_3 < 0);
116 }
117
118
119 PUBLIC int
vrna_move_is_insertion(const vrna_move_t * m)120 vrna_move_is_insertion(const vrna_move_t *m)
121 {
122 return (m->pos_5 > 0) && (m->pos_3 > 0);
123 }
124
125
126 PUBLIC int
vrna_move_is_shift(const vrna_move_t * m)127 vrna_move_is_shift(const vrna_move_t *m)
128 {
129 return ((m->pos_5 < 0) && (m->pos_3 > 0)) ||
130 ((m->pos_5 > 0) && (m->pos_3 < 0));
131 }
132
133
134 PUBLIC int
vrna_move_compare(const vrna_move_t * a,const vrna_move_t * b,const short * ptable)135 vrna_move_compare(const vrna_move_t *a,
136 const vrna_move_t *b,
137 const short *ptable)
138 {
139 /* assume, both moves a and b are compatible with current structure */
140
141 if (vrna_move_is_removal(a)) {
142 if (vrna_move_is_removal(b)) {
143 if (a->pos_5 > b->pos_5)
144 return 1;
145 else if (a->pos_5 < b->pos_5)
146 return -1;
147 else
148 return 0;
149 } else if (vrna_move_is_insertion(b)) {
150 return 1;
151 } else {
152 /*
153 * 'b' is shift move
154 * Implement me!
155 */
156 }
157 } else if (vrna_move_is_insertion(a)) {
158 if (vrna_move_is_insertion(b)) {
159 if (a->pos_5 < b->pos_5)
160 return -1;
161 else if (a->pos_5 > b->pos_5)
162 return 1;
163 else if (a->pos_3 < b->pos_3)
164 return -1;
165 else if (a->pos_3 > b->pos_3)
166 return 1;
167 else
168 return 0;
169 } else if (vrna_move_is_removal(b)) {
170 return -1;
171 } else {
172 /*
173 * 'b' is shift move
174 * Implement me!
175 */
176 }
177 } else {
178 /*
179 * 'a' is shift move
180 * Implement me!
181 */
182 }
183
184 return 0;
185 }
186