1 /* gcc -fopenmp -g3 -DTEST_FINDPATH findpath.c -o FINDpath -lRNA -lm -I../ -L./ */
2
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <limits.h>
11
12 #include "ViennaRNA/datastructures/basic.h"
13 #include "ViennaRNA/model.h"
14 #include "ViennaRNA/params/basic.h"
15 #include "ViennaRNA/fold.h"
16 #include "ViennaRNA/cofold.h"
17 #include "ViennaRNA/fold_vars.h"
18 #include "ViennaRNA/utils/basic.h"
19 #include "ViennaRNA/utils/strings.h"
20 #include "ViennaRNA/utils/structures.h"
21 #include "ViennaRNA/landscape/findpath.h"
22
23
24 #ifndef VRNA_DISABLE_BACKWARD_COMPATIBILITY
25
26 #ifdef _OPENMP
27 #include <omp.h>
28 #endif
29
30 #endif
31
32 #define LOOP_EN
33
34 #define PATH_DIRECT_FINDPATH 1U
35
36 /**
37 * @brief
38 */
39 typedef struct move {
40 int i; /* i,j>0 insert; i,j<0 delete */
41 int j;
42 int when; /* 0 if still available, else resulting distance from start */
43 int E;
44 } move_t;
45
46 /**
47 * @brief
48 */
49 typedef struct intermediate {
50 short *pt; /**< @brief pair table */
51 int Sen; /**< @brief saddle energy so far */
52 int curr_en; /**< @brief current energy */
53 move_t *moves; /**< @brief remaining moves to target */
54 } intermediate_t;
55
56
57 struct vrna_path_options_s {
58 unsigned int type;
59 unsigned int method;
60
61 int width;
62 };
63
64 /*
65 #################################
66 # GLOBAL VARIABLES #
67 #################################
68 */
69
70 /*
71 #################################
72 # PRIVATE VARIABLES #
73 #################################
74 */
75 PRIVATE int BP_dist;
76 PRIVATE move_t *path = NULL;
77 PRIVATE int path_fwd; /* 1: s1->s2, else s2 -> s1 */
78
79
80 #ifndef VRNA_DISABLE_BACKWARD_COMPATIBILITY
81
82 PRIVATE vrna_fold_compound_t *backward_compat_compound = NULL;
83
84 #ifdef _OPENMP
85
86 /* NOTE: all variables are assumed to be uninitialized if they are declared as threadprivate
87 */
88 #pragma omp threadprivate(BP_dist, path, path_fwd, backward_compat_compound)
89
90 #endif
91
92 #endif
93
94 /*
95 #################################
96 # PRIVATE FUNCTION DECLARATIONS #
97 #################################
98 */
99 PRIVATE move_t *
100 copy_moves(move_t *mvs);
101
102
103 PRIVATE int
104 compare_ptable(const void *A,
105 const void *B);
106
107
108 PRIVATE int
109 compare_energy(const void *A,
110 const void *B);
111
112
113 PRIVATE int
114 compare_moves_when(const void *A,
115 const void *B);
116
117
118 PRIVATE void
119 free_intermediate(intermediate_t *i);
120
121
122 #ifdef TEST_FINDPATH
123
124 /* TEST_FINDPATH, COFOLD */
125 PRIVATE void
126 usage(void);
127
128
129 #endif
130
131 PRIVATE int
132 find_path_once(vrna_fold_compound_t *vc,
133 short *pt1,
134 short *pt2,
135 int maxl,
136 int maxE);
137
138
139 PRIVATE int
140 try_moves(vrna_fold_compound_t *vc,
141 intermediate_t c,
142 int maxE,
143 intermediate_t *next,
144 int dist);
145
146
147 /*
148 #################################
149 # BEGIN OF FUNCTION DEFINITIONS #
150 #################################
151 */
152 PUBLIC void
vrna_path_free(vrna_path_t * path)153 vrna_path_free(vrna_path_t *path)
154 {
155 vrna_path_t *tmp = path;
156
157 if (tmp) {
158 if (tmp->type == VRNA_PATH_TYPE_DOT_BRACKET) {
159 while (tmp->s) {
160 free(tmp->s);
161 tmp++;
162 }
163 } else if (tmp->type == VRNA_PATH_TYPE_MOVES) {
164 while ((tmp->move.pos_5)) {
165 vrna_move_list_free(tmp->move.next);
166 tmp++;
167 }
168 }
169
170 free(path);
171 }
172 }
173
174
175 PUBLIC int
vrna_path_findpath_saddle(vrna_fold_compound_t * vc,const char * s1,const char * s2,int width)176 vrna_path_findpath_saddle(vrna_fold_compound_t *vc,
177 const char *s1,
178 const char *s2,
179 int width)
180 {
181 return vrna_path_findpath_saddle_ub(vc, s1, s2, width, INT_MAX - 1);
182 }
183
184
185 PUBLIC int
vrna_path_findpath_saddle_ub(vrna_fold_compound_t * vc,const char * s1,const char * s2,int width,int maxE)186 vrna_path_findpath_saddle_ub(vrna_fold_compound_t *vc,
187 const char *s1,
188 const char *s2,
189 int width,
190 int maxE)
191 {
192 int maxl;
193 short *ptr, *pt1, *pt2;
194 move_t *bestpath = NULL;
195 int dir;
196
197 path_fwd = dir = 0;
198 pt1 = vrna_ptable(s1);
199 pt2 = vrna_ptable(s2);
200
201 maxl = 1;
202 do {
203 int saddleE;
204 path_fwd = !path_fwd;
205 if (maxl > width)
206 maxl = width;
207
208 if (path)
209 free(path);
210
211 saddleE = find_path_once(vc, pt1, pt2, maxl, maxE);
212 if (saddleE < maxE) {
213 maxE = saddleE;
214 if (bestpath)
215 free(bestpath);
216
217 bestpath = path;
218 path = NULL;
219 dir = path_fwd;
220 } else {
221 free(path);
222 path = NULL;
223 }
224
225 ptr = pt1;
226 pt1 = pt2;
227 pt2 = ptr;
228 maxl *= 2;
229 } while (maxl < 2 * width);
230
231 /* (re)set some globals */
232 path = bestpath;
233 path_fwd = dir;
234
235 free(pt1);
236 free(pt2);
237
238 return maxE;
239 }
240
241
242 PUBLIC vrna_path_t *
vrna_path_findpath(vrna_fold_compound_t * fc,const char * s1,const char * s2,int width)243 vrna_path_findpath(vrna_fold_compound_t *fc,
244 const char *s1,
245 const char *s2,
246 int width)
247 {
248 struct vrna_path_options_s *opt;
249 vrna_path_t *path;
250
251 opt = vrna_path_options_findpath(width, VRNA_PATH_TYPE_DOT_BRACKET);
252 path = vrna_path_direct_ub(fc,
253 s1,
254 s2,
255 INT_MAX - 1,
256 opt);
257
258 free(opt);
259
260 return path;
261 }
262
263
264 PUBLIC vrna_path_t *
vrna_path_findpath_ub(vrna_fold_compound_t * fc,const char * s1,const char * s2,int width,int maxE)265 vrna_path_findpath_ub(vrna_fold_compound_t *fc,
266 const char *s1,
267 const char *s2,
268 int width,
269 int maxE)
270 {
271 struct vrna_path_options_s *opt;
272 vrna_path_t *path;
273
274 opt = vrna_path_options_findpath(width, VRNA_PATH_TYPE_DOT_BRACKET);
275 path = vrna_path_direct_ub(fc,
276 s1,
277 s2,
278 maxE,
279 opt);
280
281 free(opt);
282
283 return path;
284 }
285
286
287 PUBLIC struct vrna_path_options_s *
vrna_path_options_findpath(int width,unsigned int type)288 vrna_path_options_findpath(int width,
289 unsigned int type)
290 {
291 struct vrna_path_options_s *options =
292 (struct vrna_path_options_s *)vrna_alloc(sizeof(struct vrna_path_options_s));
293
294 options->type = type;
295 options->method = PATH_DIRECT_FINDPATH;
296 options->width = width;
297
298 return options;
299 }
300
301
302 PUBLIC void
vrna_path_options_free(struct vrna_path_options_s * options)303 vrna_path_options_free(struct vrna_path_options_s *options)
304 {
305 free(options);
306 }
307
308
309 PRIVATE vrna_path_t *
findpath_method(vrna_fold_compound_t * fc,const char * s1,const char * s2,int width,int maxE,unsigned int return_type)310 findpath_method(vrna_fold_compound_t *fc,
311 const char *s1,
312 const char *s2,
313 int width,
314 int maxE,
315 unsigned int return_type)
316 {
317 int E, d;
318 float last_E;
319 vrna_path_t *route = NULL;
320
321 E = vrna_path_findpath_saddle_ub(fc, s1, s2, width, maxE);
322
323 /* did we find a better path than one with saddle maxE? */
324 if (E < maxE) {
325 route = (vrna_path_t *)vrna_alloc((BP_dist + 2) * sizeof(vrna_path_t));
326
327 qsort(path, BP_dist, sizeof(move_t), compare_moves_when);
328
329 switch (return_type) {
330 case VRNA_PATH_TYPE_MOVES:
331 if (path_fwd) {
332 last_E = vrna_eval_structure(fc, s1);
333 for (d = 0; d < BP_dist; d++) {
334 route[d].type = return_type;
335 route[d].move = vrna_move_init(path[d].i,
336 path[d].j);
337 route[d].en = (path[d].E / 100.0) - last_E;
338 last_E = path[d].E / 100.0;
339 }
340
341 route[BP_dist].type = return_type;
342 route[BP_dist].move = vrna_move_init(0, 0);
343 } else {
344 last_E = vrna_eval_structure(fc, s2);
345 for (d = 0; d < BP_dist; d++) {
346 route[BP_dist - d - 2].type = return_type;
347 route[BP_dist - d - 2].move = vrna_move_init(path[d].i,
348 path[d].j);
349 route[BP_dist - d - 2].en = last_E - (path[d].E / 100.0);
350 last_E = path[d].E / 100;
351 }
352
353 route[BP_dist].type = return_type;
354 route[BP_dist].move = vrna_move_init(0, 0);
355 }
356
357 break;
358
359 case VRNA_PATH_TYPE_DOT_BRACKET:
360 /* fall through */
361
362 default:
363 if (path_fwd) {
364 /* memorize start of path */
365 route[0].type = return_type;
366 route[0].s = strdup(s1);
367 route[0].en = vrna_eval_structure(fc, s1);
368
369 for (d = 0; d < BP_dist; d++) {
370 int i, j;
371 route[d + 1].type = return_type;
372 route[d + 1].s = strdup(route[d].s);
373 i = path[d].i;
374 j = path[d].j;
375 if (i < 0) {
376 /* delete */
377 route[d + 1].s[(-i) - 1] = route[d + 1].s[(-j) - 1] = '.';
378 } else {
379 route[d + 1].s[i - 1] = '(';
380 route[d + 1].s[j - 1] = ')';
381 }
382
383 route[d + 1].en = path[d].E / 100.0;
384 }
385 } else {
386 /* memorize start of path */
387 route[0].type = return_type;
388 route[BP_dist].s = strdup(s2);
389 route[BP_dist].en = vrna_eval_structure(fc, s2);
390
391 for (d = 0; d < BP_dist; d++) {
392 int i, j;
393 route[BP_dist - d - 1].type = return_type;
394 route[BP_dist - d - 1].s = strdup(route[BP_dist - d].s);
395 i = path[d].i;
396 j = path[d].j;
397 if (i < 0) {
398 /* delete */
399 route[BP_dist - d - 1].s[(-i) - 1] = route[BP_dist - d - 1].s[(-j) - 1] = '.';
400 } else {
401 route[BP_dist - d - 1].s[i - 1] = '(';
402 route[BP_dist - d - 1].s[j - 1] = ')';
403 }
404
405 route[BP_dist - d - 1].en = path[d].E / 100.0;
406 }
407 }
408
409 break;
410 }
411
412 #if _DEBUG_FINDPATH_
413 if (return_type & VRNA_PATH_TYPE_DOT_BRACKET) {
414 fprintf(stderr, "\n%s\n%s\n%s\n\n", seq, s1, s2);
415 for (d = 0; d <= BP_dist; d++)
416 fprintf(stderr, "%s %6.2f\n", route[d].s, route[d].en);
417 fprintf(stderr, "%d\n", *num_entry);
418 }
419
420 #endif
421 }
422
423 free(path);
424 path = NULL;
425
426 return route;
427 }
428
429
430 PUBLIC vrna_path_t *
vrna_path_direct(vrna_fold_compound_t * fc,const char * s1,const char * s2,struct vrna_path_options_s * options)431 vrna_path_direct(vrna_fold_compound_t *fc,
432 const char *s1,
433 const char *s2,
434 struct vrna_path_options_s *options)
435 {
436 return vrna_path_direct_ub(fc,
437 s1,
438 s2,
439 INT_MAX - 1,
440 options);
441 }
442
443
444 PUBLIC vrna_path_t *
vrna_path_direct_ub(vrna_fold_compound_t * fc,const char * s1,const char * s2,int maxE,struct vrna_path_options_s * options)445 vrna_path_direct_ub(vrna_fold_compound_t *fc,
446 const char *s1,
447 const char *s2,
448 int maxE,
449 struct vrna_path_options_s *options)
450 {
451 int E, d;
452 struct vrna_path_options_s *o;
453 vrna_path_t *route = NULL;
454
455 /* we default to findpath method */
456 o = options ? options : vrna_path_options_findpath(10,
457 VRNA_PATH_TYPE_DOT_BRACKET);
458
459 switch (o->method) {
460 case PATH_DIRECT_FINDPATH:
461 /* fall through */
462 default:
463 route = findpath_method(fc, s1, s2, o->width, maxE, o->type);
464 break;
465 }
466
467 if (!options)
468 vrna_path_options_free(o);
469
470 return route;
471 }
472
473
474 #ifdef TEST_FINDPATH
475
476 PUBLIC void
print_path(const char * seq,const char * struc)477 print_path(const char *seq,
478 const char *struc)
479 {
480 int d;
481 char *s;
482
483 s = strdup(struc);
484 if (cut_point == -1) {
485 printf("%s\n%s\n", seq, s);
486 }
487 /* printf("%s\n%s %6.2f\n", seq, s, vrna_eval_structure_simple(seq,s)); */
488 else {
489 char *pstruct, *pseq;
490 pstruct = vrna_cut_point_insert(s, cut_point);
491 pseq = vrna_cut_point_insert(seq, cut_point);
492 printf("%s\n%s\n", pseq, pstruct);
493 /* printf("%s\n%s %6.2f\n", pseq, pstruct, vrna_eval_structure_simple(seq,s)); */
494 free(pstruct);
495 free(pseq);
496 }
497
498 qsort(path, BP_dist, sizeof(move_t), compare_moves_when);
499 for (d = 0; d < BP_dist; d++) {
500 int i, j;
501 i = path[d].i;
502 j = path[d].j;
503 if (i < 0) {
504 /* delete */
505 s[(-i) - 1] = s[(-j) - 1] = '.';
506 } else {
507 s[i - 1] = '(';
508 s[j - 1] = ')';
509 }
510
511 /* printf("%s %6.2f - %6.2f\n", s, vrna_eval_structure_simple(seq,s), path[d].E/100.0); */
512 }
513 free(s);
514 }
515
516
517 int
main(int argc,char * argv[])518 main(int argc,
519 char *argv[])
520 {
521 char *line, *seq, *s1, *s2;
522 int E, maxkeep = 1000;
523 int verbose = 0, i;
524 vrna_path_t *route, *r;
525
526 for (i = 1; i < argc; i++) {
527 switch (argv[i][1]) {
528 case 'm':
529 if (strcmp(argv[i], "-m") == 0)
530 sscanf(argv[++i], "%d", &maxkeep);
531
532 break;
533 case 'v':
534 verbose = !strcmp(argv[i], "-v");
535 break;
536 case 'd':
537 if (strcmp(argv[i], "-d") == 0)
538 sscanf(argv[++i], "%d", &dangles);
539
540 break;
541 default:
542 usage();
543 }
544 }
545
546 cut_point = -1;
547 line = vrna_read_line(stdin);
548 seq = vrna_cut_point_remove(line, &cut_point);
549 free(line);
550 line = vrna_read_line(stdin);
551 s1 = vrna_cut_point_remove(line, &cut_point);
552 free(line);
553 line = vrna_read_line(stdin);
554 s2 = vrna_cut_point_remove(line, &cut_point);
555 free(line);
556
557 E = find_saddle(seq, s1, s2, maxkeep);
558 printf("saddle_energy = %6.2f\n", E / 100.);
559 if (verbose) {
560 if (path_fwd)
561 print_path(seq, s1);
562 else
563 print_path(seq, s2);
564
565 free(path);
566 path = NULL;
567 route = get_path(seq, s1, s2, maxkeep);
568 for (r = route; r->s; r++) {
569 if (cut_point == -1) {
570 printf("%s %6.2f\n", r->s, r->en);
571 /* printf("%s %6.2f - %6.2f\n", r->s, vrna_eval_structure_simple(seq,r->s), r->en); */
572 } else {
573 char *pstruct;
574 pstruct = vrna_cut_point_insert(r->s, cut_point);
575 printf("%s %6.2f\n", pstruct, r->en);
576 /* printf("%s %6.2f - %6.2f\n", pstruct, vrna_eval_structure_simple(seq,r->s), r->en); */
577 free(pstruct);
578 }
579
580 free(r->s);
581 }
582 free(route);
583 }
584
585 free(seq);
586 free(s1);
587 free(s2);
588 return EXIT_SUCCESS;
589 }
590
591
592 static void
usage(void)593 usage(void)
594 {
595 vrna_message_error("usage: findpath.c [-m depth] [-d[0|1|2]] [-v]");
596 }
597
598
599 #endif
600
601
602 /*
603 #################################
604 # STATIC helper functions below #
605 #################################
606 */
607 PRIVATE int
try_moves(vrna_fold_compound_t * vc,intermediate_t c,int maxE,intermediate_t * next,int dist)608 try_moves(vrna_fold_compound_t *vc,
609 intermediate_t c,
610 int maxE,
611 intermediate_t *next,
612 int dist)
613 {
614 int *loopidx, len, num_next = 0, en, oldE;
615 move_t *mv;
616 short *pt;
617
618 len = c.pt[0];
619 loopidx = vrna_loopidx_from_ptable(c.pt);
620 oldE = c.Sen;
621 for (mv = c.moves; mv->i != 0; mv++) {
622 int i, j;
623 if (mv->when > 0)
624 continue;
625
626 i = mv->i;
627 j = mv->j;
628 pt = (short *)vrna_alloc(sizeof(short) * (len + 1));
629 memcpy(pt, c.pt, (len + 1) * sizeof(short));
630 if (j < 0) {
631 /*it's a delete move */
632 pt[-i] = 0;
633 pt[-j] = 0;
634 } else {
635 /* insert move */
636 if ((loopidx[i] == loopidx[j]) && /* i and j belong to same loop */
637 (pt[i] == 0) && (pt[j] == 0) /* ... and are unpaired */
638 ) {
639 pt[i] = j;
640 pt[j] = i;
641 } else {
642 free(pt);
643 continue; /* llegal move, try next; */
644 }
645 }
646
647 #ifdef LOOP_EN
648 en = c.curr_en + vrna_eval_move_pt(vc, c.pt, i, j);
649 #else
650 en = vrna_eval_structure_pt(vc, pt);
651 #endif
652 if (en < maxE) {
653 next[num_next].Sen = (en > oldE) ? en : oldE;
654 next[num_next].curr_en = en;
655 next[num_next].pt = pt;
656 mv->when = dist;
657 mv->E = en;
658 next[num_next++].moves = copy_moves(c.moves);
659 mv->when = 0;
660 } else {
661 free(pt);
662 }
663 }
664 free(loopidx);
665 return num_next;
666 }
667
668
669 PRIVATE int
find_path_once(vrna_fold_compound_t * vc,short * pt1,short * pt2,int maxl,int maxE)670 find_path_once(vrna_fold_compound_t *vc,
671 short *pt1,
672 short *pt2,
673 int maxl,
674 int maxE)
675 {
676 move_t *mlist;
677 int i, len, d, dist = 0, result;
678 short *pt;
679 intermediate_t *current, *next;
680
681 len = (int)pt1[0];
682 pt = vrna_ptable_copy(pt1);
683
684 mlist = (move_t *)vrna_alloc(sizeof(move_t) * len); /* bp_dist < n */
685
686 for (i = 1; i <= len; i++) {
687 if (pt[i] != pt2[i]) {
688 if (i < pt[i]) {
689 /* need to delete this pair */
690 mlist[dist].i = -i;
691 mlist[dist].j = -pt[i];
692 mlist[dist++].when = 0;
693 }
694
695 if (i < pt2[i]) {
696 /* need to insert this pair */
697 mlist[dist].i = i;
698 mlist[dist].j = pt2[i];
699 mlist[dist++].when = 0;
700 }
701 }
702 }
703
704 BP_dist = dist;
705 current = (intermediate_t *)vrna_alloc(sizeof(intermediate_t) * (maxl + 1));
706 current[0].pt = pt;
707 current[0].Sen = current[0].curr_en = vrna_eval_structure_pt(vc, pt);
708 current[0].moves = mlist;
709 next = (intermediate_t *)vrna_alloc(sizeof(intermediate_t) * (dist * maxl + 1));
710
711 for (d = 1; d <= dist; d++) {
712 /* go through the distance classes */
713 int c, u, num_next = 0;
714 intermediate_t *cc;
715
716 for (c = 0; current[c].pt != NULL; c++)
717 num_next += try_moves(vc, current[c], maxE, next + num_next, d);
718 if (num_next == 0) {
719 for (cc = current; cc->pt != NULL; cc++)
720 free_intermediate(cc);
721 current[0].Sen = INT_MAX;
722 break;
723 }
724
725 /* remove duplicates via sort|uniq
726 * if this becomes a bottleneck we can use a hash instead */
727 qsort(next, num_next, sizeof(intermediate_t), compare_ptable);
728 for (u = 0, c = 1; c < num_next; c++) {
729 if (memcmp(next[u].pt, next[c].pt, sizeof(short) * len) != 0)
730 next[++u] = next[c];
731 else
732 free_intermediate(next + c);
733 }
734 num_next = u + 1;
735 qsort(next, num_next, sizeof(intermediate_t), compare_energy);
736 /* free the old stuff */
737 for (cc = current; cc->pt != NULL; cc++)
738 free_intermediate(cc);
739 for (u = 0; u < maxl && u < num_next; u++)
740 current[u] = next[u];
741 for (; u < num_next; u++)
742 free_intermediate(next + u);
743 num_next = 0;
744 }
745 free(next);
746 path = current[0].moves;
747 result = current[0].Sen;
748 free(current[0].pt);
749 free(current);
750 return result;
751 }
752
753
754 PRIVATE void
free_intermediate(intermediate_t * i)755 free_intermediate(intermediate_t *i)
756 {
757 free(i->pt);
758 free(i->moves);
759 i->pt = NULL;
760 i->moves = NULL;
761 i->Sen = INT_MAX;
762 }
763
764
765 PRIVATE int
compare_ptable(const void * A,const void * B)766 compare_ptable(const void *A,
767 const void *B)
768 {
769 intermediate_t *a, *b;
770 int c;
771
772 a = (intermediate_t *)A;
773 b = (intermediate_t *)B;
774
775 c = memcmp(a->pt, b->pt, a->pt[0] * sizeof(short));
776 if (c != 0)
777 return c;
778
779 if ((a->Sen - b->Sen) != 0)
780 return a->Sen - b->Sen;
781
782 return a->curr_en - b->curr_en;
783 }
784
785
786 PRIVATE int
compare_energy(const void * A,const void * B)787 compare_energy(const void *A,
788 const void *B)
789 {
790 intermediate_t *a, *b;
791
792 a = (intermediate_t *)A;
793 b = (intermediate_t *)B;
794
795 if ((a->Sen - b->Sen) != 0)
796 return a->Sen - b->Sen;
797
798 return a->curr_en - b->curr_en;
799 }
800
801
802 PRIVATE int
compare_moves_when(const void * A,const void * B)803 compare_moves_when(const void *A,
804 const void *B)
805 {
806 move_t *a, *b;
807
808 a = (move_t *)A;
809 b = (move_t *)B;
810
811 return a->when - b->when;
812 }
813
814
815 PRIVATE move_t *
copy_moves(move_t * mvs)816 copy_moves(move_t *mvs)
817 {
818 move_t *new;
819
820 new = (move_t *)vrna_alloc(sizeof(move_t) * (BP_dist + 1));
821 memcpy(new, mvs, sizeof(move_t) * (BP_dist + 1));
822 return new;
823 }
824
825
826 /*
827 *###########################################
828 *# deprecated functions below #
829 *###########################################
830 */
831
832 #ifndef VRNA_DISABLE_BACKWARD_COMPATIBILITY
833
834 PUBLIC void
free_path(vrna_path_t * path)835 free_path(vrna_path_t *path)
836 {
837 vrna_path_free(path);
838 }
839
840
841 PUBLIC int
find_saddle(const char * seq,const char * s1,const char * s2,int width)842 find_saddle(const char *seq,
843 const char *s1,
844 const char *s2,
845 int width)
846 {
847 int maxE;
848 char *sequence;
849 vrna_fold_compound_t *vc;
850 vrna_md_t md, *md_p;
851
852 vc = NULL;
853 set_model_details(&md);
854
855 if (backward_compat_compound) {
856 if (!strcmp(seq, backward_compat_compound->sequence)) {
857 /* check if sequence is the same as before */
858 md.window_size = backward_compat_compound->length;
859 md.max_bp_span = backward_compat_compound->length;
860 md_p = &(backward_compat_compound->params->model_details);
861 if (!memcmp(&md, md_p, sizeof(vrna_md_t))) /* check if model_details are the same as before */
862 vc = backward_compat_compound; /* re-use previous vrna_fold_compound_t */
863 }
864 }
865
866 if (!vc) {
867 vrna_fold_compound_free(backward_compat_compound);
868
869 sequence = vrna_cut_point_insert(seq, cut_point);
870
871 backward_compat_compound = vc = vrna_fold_compound(sequence, &md, VRNA_OPTION_EVAL_ONLY);
872
873 free(sequence);
874 }
875
876 maxE = vrna_path_findpath_saddle(vc, s1, s2, width);
877
878 return maxE;
879 }
880
881
882 PUBLIC vrna_path_t *
get_path(const char * seq,const char * s1,const char * s2,int maxkeep)883 get_path(const char *seq,
884 const char *s1,
885 const char *s2,
886 int maxkeep)
887 {
888 vrna_path_t *route = NULL;
889 char *sequence = NULL;
890 vrna_fold_compound_t *vc = NULL;
891 vrna_md_t md, *md_p;
892
893 set_model_details(&md);
894
895 if (backward_compat_compound) {
896 if (!strcmp(seq, backward_compat_compound->sequence)) {
897 /* check if sequence is the same as before */
898 md.window_size = backward_compat_compound->length;
899 md.max_bp_span = backward_compat_compound->length;
900 md_p = &(backward_compat_compound->params->model_details);
901 if (!memcmp(&md, md_p, sizeof(vrna_md_t))) /* check if model_details are the same as before */
902 vc = backward_compat_compound; /* re-use previous vrna_fold_compound_t */
903 }
904 }
905
906 if (!vc) {
907 vrna_fold_compound_free(backward_compat_compound);
908
909 sequence = vrna_cut_point_insert(seq, cut_point);
910
911 backward_compat_compound = vc = vrna_fold_compound(sequence, &md, VRNA_OPTION_EVAL_ONLY);
912
913 free(sequence);
914 }
915
916 route = vrna_path_findpath(vc, s1, s2, maxkeep);
917
918 return route;
919 }
920
921
922 #endif
923