1 /*
2  ###################################
3  # convert energy parameter files  #
4  # from ViennaRNAPackage 1.8.4 to  #
5  # 2.0 format                      #
6  #                                 #
7  # Ronny Lorenz                    #
8  ###################################
9  */
10 
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <ctype.h>
18 #include <string.h>
19 #include <math.h>
20 
21 #include "ViennaRNA/utils/basic.h"
22 #include "ViennaRNA/fold_vars.h"
23 #include "ViennaRNA/params/io.h"
24 #include "ViennaRNA/io/utils.h"
25 #include "ViennaRNA/pair_mat.h"
26 
27 #include "1.8.4_epars.h"
28 #include "1.8.4_intloops.h"
29 
30 #include "ViennaRNA/params/convert.h"
31 
32 enum parset_184 {
33   UNKNOWN_184= -1, QUIT_184,
34   S_184, SH_184, HP_184, B_184, IL_184, MMI_184, MMH_184, MMM_184, MM_H_184,
35   DE5_184, DE3_184, DE5_H_184, DE3_H_184, ML_184, TL_184, TRI_184, TE_184, NIN_184, MISC_184,
36   INT11_184, INT11_H_184, INT21_184, INT21_H_184, INT22_184, INT22_H_184
37 };
38 
39 
40 PRIVATE unsigned int
41 read_old_parameter_file(FILE  *ifile,
42                         int   skip_header);
43 
44 
45 PRIVATE void
46 write_new_parameter_file(FILE         *ofile,
47                          unsigned int options);
48 
49 
50 PRIVATE void
51 rd_stacks(int   stack[NBPAIRS + 1][NBPAIRS + 1],
52           FILE  *fp);
53 
54 
55 PRIVATE void
56 rd_loop(int   looparray[31],
57         FILE  *fp);
58 
59 
60 PRIVATE void
61 rd_mismatch(int   mismatch[NBPAIRS + 1][5][5],
62             FILE  *fp);
63 
64 
65 PRIVATE void
66 rd_int11(int  int11[NBPAIRS + 1][NBPAIRS + 1][5][5],
67          FILE *fp);
68 
69 
70 PRIVATE void
71 rd_int21(int  int21[NBPAIRS + 1][NBPAIRS + 1][5][5][5],
72          FILE *fp);
73 
74 
75 PRIVATE void
76 rd_int22(int  int22[NBPAIRS + 1][NBPAIRS + 1][5][5][5][5],
77          FILE *fp);
78 
79 
80 PRIVATE void
81 rd_dangle(int   dangles[NBPAIRS + 1][5],
82           FILE  *fp);
83 
84 
85 PRIVATE void
86 rd_MLparams(FILE *fp);
87 
88 
89 PRIVATE void
90 rd_misc(FILE *fp);
91 
92 
93 PRIVATE void
94 rd_ninio(FILE *fp);
95 
96 
97 PRIVATE void
98 rd_Tetra_loop(FILE *fp);
99 
100 
101 PRIVATE void
102 rd_Tri_loop(FILE *fp);
103 
104 
105 PRIVATE void
106 check_symmetry(void);
107 
108 
109 PRIVATE enum
110 parset_184 gettype_184(char ident[]);
111 
112 
113 PRIVATE char *
114 get_array1(int  *arr,
115            int  size,
116            FILE *fp);
117 
118 
119 PRIVATE void
120 ignore_comment(char *line);
121 
122 
123 PRIVATE void
124 display_array(int   *p,
125               int   size,
126               int   line,
127               FILE  *fp);
128 
129 
130 PUBLIC void
convert_parameter_file(const char * iname,const char * oname,unsigned int options)131 convert_parameter_file(const char   *iname,
132                        const char   *oname,
133                        unsigned int options)
134 {
135   FILE          *ifile, *ofile;
136   unsigned int  old_options       = 0;
137   int           skip_input_header = 0;
138 
139   if (options & VRNA_CONVERT_OUTPUT_DUMP) {
140     if (oname == NULL)
141       oname = iname;
142 
143     skip_input_header = 1;
144   } else {
145     if (iname == NULL) {
146       ifile             = stdin;
147       skip_input_header = 1;
148     } else if (!(ifile = fopen(iname, "r"))) {
149       vrna_message_warning("convert_epars: can't open file %s", iname);
150       return;
151     }
152 
153     /* read old (1.8.4 format) parameter file */
154     old_options = read_old_parameter_file(ifile, skip_input_header);
155     if (ifile != stdin)
156       fclose(ifile);
157 
158     check_symmetry();
159   }
160 
161   if (options & VRNA_CONVERT_OUTPUT_VANILLA)
162     options = old_options;
163 
164   if (oname == NULL) {
165     ofile = stdout;
166   } else if (!(ofile = fopen(oname, "a+"))) {
167     vrna_message_warning("convert_epars: can't open file %s for writing", oname);
168     return;
169   }
170 
171   write_new_parameter_file(ofile, options);
172   if (ofile != stdout)
173     fclose(ofile);
174 }
175 
176 
177 /*------------------------------------------------------------*/
178 PRIVATE unsigned int
read_old_parameter_file(FILE * ifile,int skip_header)179 read_old_parameter_file(FILE  *ifile,
180                         int   skip_header)
181 {
182   char                  *line, ident[32];
183   enum      parset_184  type;
184   int                   r, last;
185   unsigned int          read_successfully = 0;
186 
187   if (!(line = vrna_read_line(ifile))) {
188     vrna_message_warning("convert_epars: can't read input parameter file");
189     return 0;
190   }
191 
192   if (!skip_header) {
193     if (strncmp(line, "## RNAfold parameter file", 25) != 0) {
194       vrna_message_warning("convert_epars: Missing header line in input parameter file.\n"
195                            "May be this file has incorrect format?");
196       free(line);
197       return 0;
198     }
199 
200     free(line);
201     line = vrna_read_line(ifile);
202   }
203 
204   last = 0;
205   do {
206     r = sscanf(line, "# %31s", ident);
207     if (r == 1) {
208       type = gettype_184(ident);
209       switch (type) {
210         case QUIT_184:
211           if (ifile == stdin) {
212             vrna_message_info(stderr, "press ENTER to continue...");
213             fflush(stderr);
214           }
215 
216           last = 1;
217           break;
218         case SH_184:
219           rd_stacks(enthalpies_184, ifile);
220           read_successfully |= VRNA_CONVERT_OUTPUT_STACK;
221           break;
222         case S_184:
223           rd_stacks(stack37_184, ifile);
224           read_successfully |= VRNA_CONVERT_OUTPUT_STACK;
225           break;
226         case HP_184:
227           rd_loop(hairpin37_184, ifile);
228           read_successfully |= VRNA_CONVERT_OUTPUT_HP;
229           break;
230         case B_184:
231           rd_loop(bulge37_184, ifile);
232           read_successfully |= VRNA_CONVERT_OUTPUT_BULGE;
233           break;
234         case IL_184:
235           rd_loop(internal_loop37_184, ifile);
236           read_successfully |= VRNA_CONVERT_OUTPUT_INT;
237           break;
238         case MMH_184:
239           rd_mismatch(mismatchH37_184, ifile);
240           read_successfully |= VRNA_CONVERT_OUTPUT_MM_HP;
241           break;
242         case MMI_184:
243           rd_mismatch(mismatchI37_184, ifile);
244           read_successfully |= VRNA_CONVERT_OUTPUT_MM_INT
245                                | VRNA_CONVERT_OUTPUT_MM_INT_1N                /* since 1:n-interior loop mismatches are treated seperately in 2.0 */
246                                | VRNA_CONVERT_OUTPUT_MM_INT_23;               /* since 2:3-interior loop mismatches are treated seperately in 2.0 */
247           break;
248         case MMM_184:
249           rd_mismatch(mismatchM37_184, ifile);
250           read_successfully |= VRNA_CONVERT_OUTPUT_MM_MULTI;
251           break;
252         case MM_H_184:
253           rd_mismatch(mism_H_184, ifile);
254           read_successfully |= VRNA_CONVERT_OUTPUT_MM_HP                      /* since hairpin mismatches are treated seperately in 2.0 */
255                                | VRNA_CONVERT_OUTPUT_MM_INT                   /* since interior loop  mismatches are treated seperately in 2.0 */
256                                | VRNA_CONVERT_OUTPUT_MM_INT_1N                /* since 1:n-interior loop mismatches are treated seperately in 2.0 */
257                                | VRNA_CONVERT_OUTPUT_MM_INT_23                /* since 2:3-interior loop mismatches are treated seperately in 2.0 */
258                                | VRNA_CONVERT_OUTPUT_MM_MULTI;                /* since multi loop mismatches are treated seperately in 2.0 */
259           break;
260         case INT11_184:
261           rd_int11(int11_37_184, ifile);
262           read_successfully |= VRNA_CONVERT_OUTPUT_INT_11;
263           break;
264         case INT11_H_184:
265           rd_int11(int11_H_184, ifile);
266           read_successfully |= VRNA_CONVERT_OUTPUT_INT_11;
267           break;
268         case INT21_184:
269           rd_int21(int21_37_184, ifile);
270           read_successfully |= VRNA_CONVERT_OUTPUT_INT_21;
271           break;
272         case INT21_H_184:
273           rd_int21(int21_H_184, ifile);
274           read_successfully |= VRNA_CONVERT_OUTPUT_INT_21;
275           break;
276         case INT22_184:
277           rd_int22(int22_37_184, ifile);
278           read_successfully |= VRNA_CONVERT_OUTPUT_INT_22;
279           break;
280         case INT22_H_184:
281           rd_int22(int22_H_184, ifile);
282           read_successfully |= VRNA_CONVERT_OUTPUT_INT_22;
283           break;
284         case DE5_184:
285           rd_dangle(dangle5_37_184, ifile);
286           read_successfully |= VRNA_CONVERT_OUTPUT_DANGLE5
287                                | VRNA_CONVERT_OUTPUT_MM_MULTI               /* since multi loop mismatches were treated as dangle contribution */
288                                | VRNA_CONVERT_OUTPUT_MM_EXT;                /* since exterior loop mismatches were treated as dangle contribution */
289           break;
290         case DE5_H_184:
291           rd_dangle(dangle5_H_184, ifile);
292           read_successfully |= VRNA_CONVERT_OUTPUT_DANGLE5
293                                | VRNA_CONVERT_OUTPUT_MM_MULTI               /* since multi loop mismatches were treated as dangle contribution */
294                                | VRNA_CONVERT_OUTPUT_MM_EXT;                /* since exterior loop mismatches were treated as dangle contribution */
295           break;
296         case DE3_184:
297           rd_dangle(dangle3_37_184, ifile);
298           read_successfully |= VRNA_CONVERT_OUTPUT_DANGLE3
299                                | VRNA_CONVERT_OUTPUT_MM_MULTI               /* since multi loop mismatches were treated as dangle contribution */
300                                | VRNA_CONVERT_OUTPUT_MM_EXT;                /* since exterior loop mismatches were treated as dangle contribution */
301           break;
302         case DE3_H_184:
303           rd_dangle(dangle3_H_184, ifile);
304           read_successfully |= VRNA_CONVERT_OUTPUT_DANGLE3
305                                | VRNA_CONVERT_OUTPUT_MM_MULTI               /* since multi loop mismatches were treated as dangle contribution */
306                                | VRNA_CONVERT_OUTPUT_MM_EXT;                /* since exterior loop mismatches were treated as dangle contribution */
307           break;
308         case ML_184:
309           rd_MLparams(ifile);
310           read_successfully |= VRNA_CONVERT_OUTPUT_ML
311                                | VRNA_CONVERT_OUTPUT_MISC;                  /* since TerminalAU went to "misc" section */
312           break;
313         case NIN_184:
314           rd_ninio(ifile);
315           read_successfully |= VRNA_CONVERT_OUTPUT_NINIO;
316           break;
317         case TL_184:
318           rd_Tetra_loop(ifile);
319           read_successfully |= VRNA_CONVERT_OUTPUT_SPECIAL_HP;
320           break;
321         case TRI_184:
322           rd_Tri_loop(ifile);
323           read_successfully |= VRNA_CONVERT_OUTPUT_SPECIAL_HP;
324           break;
325         case MISC_184:
326           rd_misc(ifile);
327           read_successfully |= VRNA_CONVERT_OUTPUT_MISC;
328           break;
329         default:          /* do nothing but complain */
330           vrna_message_warning("convert_parameter_file: Unknown field identifier in `%s'", line);
331       }
332     } /* else ignore line */
333 
334     free(line);
335   } while ((line = vrna_read_line(ifile)) && !last);
336   return read_successfully;
337 }
338 
339 
340 PRIVATE void
display_array(int * p,int size,int nl,FILE * fp)341 display_array(int   *p,
342               int   size,
343               int   nl,
344               FILE  *fp)
345 {
346   int i;
347 
348   for (i = 1; i <= size; i++, p++) {
349     switch (*p) {
350       case  INF:
351         fprintf(fp, "   INF");
352         break;
353       case -INF:
354         fprintf(fp, "  -INf");
355         break;
356       case  DEF:
357         fprintf(fp, "   DEF");
358         break;
359       default:
360         fprintf(fp, "%6d", *p);
361         break;
362     }
363     if ((i % nl) == 0)
364       fprintf(fp, "\n");
365   }
366   if (size % nl)
367     fprintf(fp, "\n");
368 
369   return;
370 }
371 
372 
373 PRIVATE char *
get_array1(int * arr,int size,FILE * fp)374 get_array1(int  *arr,
375            int  size,
376            FILE *fp)
377 {
378   int   i, p, pos, pp, r, last;
379   char  *line, buf[16];
380 
381   i = last = 0;
382   while (i < size) {
383     line = vrna_read_line(fp);
384     if (!line)
385       vrna_message_error("convert_epars: unexpected end of file in get_array1");
386 
387     ignore_comment(line);
388     pos = 0;
389     while ((i < size) && (sscanf(line + pos, "%15s%n", buf, &pp) == 1)) {
390       pos += pp;
391       if (buf[0] == '*') {
392         i++;
393         continue;
394       } else if (buf[0] == 'x') {
395         /* should only be used for loop parameters */
396         if (i == 0)
397           vrna_message_error("convert_epars: can't extrapolate first value");
398 
399         p = arr[last] + (int)(0.5 + lxc37_184 * log(((double)i) / (double)(last)));
400       } else if (strcmp(buf, "DEF") == 0) {
401         p = DEF;
402       } else if (strcmp(buf, "INF") == 0) {
403         p = INF;
404       } else if (strcmp(buf, "NST") == 0) {
405         p = NST;
406       } else {
407         r = sscanf(buf, "%d", &p);
408         if (r != 1) {
409           return line + pos;
410           vrna_message_error("convert_epars: can't interpret `%s' in get_array1", buf);
411           exit(1);
412         }
413 
414         last = i;
415       }
416 
417       arr[i++] = p;
418     }
419     free(line);
420   }
421 
422   return NULL;
423 }
424 
425 
426 /*------------------------------------------------------------*/
427 
428 PRIVATE void
rd_stacks(int stacks[NBPAIRS+1][NBPAIRS+1],FILE * fp)429 rd_stacks(int   stacks[NBPAIRS + 1][NBPAIRS + 1],
430           FILE  *fp)
431 {
432   int   i;
433   char  *cp;
434 
435   for (i = 1; i <= NBPAIRS; i++) {
436     cp = get_array1(stacks[i] + 1, NBPAIRS, fp);
437     if (cp) {
438       vrna_message_error("convert_epars: \nrd_stacks: %s", cp);
439       exit(1);
440     }
441   }
442   return;
443 }
444 
445 
446 /*------------------------------------------------------------*/
447 
448 PRIVATE void
rd_loop(int loop[31],FILE * fp)449 rd_loop(int   loop[31],
450         FILE  *fp)
451 {
452   char *cp;
453 
454   cp = get_array1(loop, 31, fp);
455 
456   if (cp) {
457     vrna_message_error("convert_epars: \nrd_loop: %s", cp);
458     exit(1);
459   }
460 
461   return;
462 }
463 
464 
465 /*------------------------------------------------------------*/
466 
467 PRIVATE void
rd_mismatch(int mismatch[NBPAIRS+1][5][5],FILE * fp)468 rd_mismatch(int   mismatch[NBPAIRS + 1][5][5],
469             FILE  *fp)
470 {
471   char  *cp;
472   int   i;
473 
474   for (i = 1; i < NBPAIRS + 1; i++) {
475     cp = get_array1(mismatch[i][0], 5 * 5, fp);
476     if (cp) {
477       vrna_message_error("convert_epars: rd_mismatch: in field mismatch[%d]\n\t%s", i, cp);
478       exit(1);
479     }
480   }
481   return;
482 }
483 
484 
485 /*------------------------------------------------------------*/
486 PRIVATE void
rd_int11(int int11[NBPAIRS+1][NBPAIRS+1][5][5],FILE * fp)487 rd_int11(int  int11[NBPAIRS + 1][NBPAIRS + 1][5][5],
488          FILE *fp)
489 {
490   char  *cp;
491   int   i, j;
492 
493   for (i = 1; i < NBPAIRS + 1; i++) {
494     for (j = 1; j < NBPAIRS + 1; j++) {
495       cp = get_array1(int11[i][j][0], 5 * 5, fp);
496       if (cp) {
497         vrna_message_error("convert_epars: rd_int11: in field int11[%d][%d]\n\t%s", i, j, cp);
498         exit(1);
499       }
500     }
501   }
502   return;
503 }
504 
505 
506 /*------------------------------------------------------------*/
507 PRIVATE void
rd_int21(int int21[NBPAIRS+1][NBPAIRS+1][5][5][5],FILE * fp)508 rd_int21(int  int21[NBPAIRS + 1][NBPAIRS + 1][5][5][5],
509          FILE *fp)
510 {
511   char  *cp;
512   int   i, j, k;
513 
514   for (i = 1; i < NBPAIRS + 1; i++) {
515     for (j = 1; j < NBPAIRS + 1; j++) {
516       for (k = 0; k < 5; k++) {
517         cp = get_array1(int21[i][j][k][0], 5 * 5, fp);
518         if (cp) {
519           vrna_message_error("convert_epars: rd_int21: in field int21[%d][%d][%d]\n\t%s",
520                              i, j, k, cp);
521           exit(1);
522         }
523       }
524     }
525   }
526   return;
527 }
528 
529 
530 /*------------------------------------------------------------*/
531 PRIVATE void
rd_int22(int int22[NBPAIRS+1][NBPAIRS+1][5][5][5][5],FILE * fp)532 rd_int22(int  int22[NBPAIRS + 1][NBPAIRS + 1][5][5][5][5],
533          FILE *fp)
534 {
535   char  *cp;
536   int   i, j, k, l, m;
537 
538   for (i = 1; i < NBPAIRS + 1; i++)
539     for (j = 1; j < NBPAIRS + 1; j++)
540       for (k = 1; k < 5; k++)
541         for (l = 1; l < 5; l++)
542           for (m = 1; m < 5; m++) {
543             cp = get_array1(int22[i][j][k][l][m] + 1, 4, fp);
544             if (cp) {
545               vrna_message_error("convert_epars: rd_int22: in field "
546                                  "int22[%d][%d][%d][%d][%d]\n\t%s",
547                                  i, j, k, l, m, cp);
548               exit(1);
549             }
550           }
551 
552   return;
553 }
554 
555 
556 /*------------------------------------------------------------*/
557 PRIVATE void
rd_dangle(int dangle[NBPAIRS+1][5],FILE * fp)558 rd_dangle(int   dangle[NBPAIRS + 1][5],
559           FILE  *fp)
560 {
561   int   i;
562   char  *cp;
563 
564   for (i = 0; i < NBPAIRS + 1; i++) {
565     cp = get_array1(dangle[i], 5, fp);
566     if (cp) {
567       vrna_message_error("convert_epars: \nrd_dangle: %s", cp);
568       exit(1);
569     }
570   }
571   return;
572 }
573 
574 
575 /*------------------------------------------------------------*/
576 PRIVATE void
rd_MLparams(FILE * fp)577 rd_MLparams(FILE *fp)
578 {
579   char  *cp;
580   int   values[4];
581 
582   cp = get_array1(values, 4, fp);
583   if (cp) {
584     vrna_message_error("convert_epars: rd_MLparams: %s", cp);
585     exit(1);
586   }
587 
588   ML_BASE37_184     = values[0];
589   ML_closing37_184  = values[1];
590   ML_intern37_184   = values[2];
591   TerminalAU_184    = values[3];
592 
593   return;
594 }
595 
596 
597 /*------------------------------------------------------------*/
598 
599 PRIVATE void
rd_misc(FILE * fp)600 rd_misc(FILE *fp)
601 {
602   char  *cp;
603   int   values[1]; /* so far just one */
604 
605   cp = get_array1(values, 1, fp);
606   if (cp) {
607     vrna_message_error("convert_epars: rd_misc: %s", cp);
608     exit(1);
609   }
610 
611   DuplexInit_184 = values[0];
612 
613   return;
614 }
615 
616 
617 /*------------------------------------------------------------*/
618 
619 PRIVATE void
rd_ninio(FILE * fp)620 rd_ninio(FILE *fp)
621 {
622   char  *cp;
623   int   temp[2];
624 
625   cp = get_array1(temp, 2, fp);
626 
627   if (cp) {
628     vrna_message_error("convert_epars: rd_F_ninio: %s", cp);
629     exit(1);
630   }
631 
632   F_ninio37_184[2]  = temp[0];
633   MAX_NINIO_184     = temp[1];
634   return;
635 }
636 
637 
638 /*------------------------------------------------------------*/
639 PRIVATE void
rd_Tetra_loop(FILE * fp)640 rd_Tetra_loop(FILE *fp)
641 {
642   int   i, r;
643   char  *buf;
644 
645   i = 0;
646   memset(&Tetraloops_184, 0, 1400);
647   memset(&TETRA_ENERGY37_184, 0, sizeof(int) * 200);
648   do {
649     buf = vrna_read_line(fp);
650     if (buf == NULL)
651       break;
652 
653     r = sscanf(buf, "%6s %d", &Tetraloops_184[7 * i], &TETRA_ENERGY37_184[i]);
654     strcat(Tetraloops_184, " ");
655     free(buf);
656     i++;
657   } while ((r == 2) && (i < 200));
658   return;
659 }
660 
661 
662 /*------------------------------------------------------------*/
663 PRIVATE void
rd_Tri_loop(FILE * fp)664 rd_Tri_loop(FILE *fp)
665 {
666   int   i, r;
667   char  *buf;
668 
669   i = 0;
670   memset(&Triloops_184, 0, 241);
671   memset(&Triloop_E37_184, 0, sizeof(int) * 40);
672   do {
673     buf = vrna_read_line(fp);
674     if (buf == NULL)
675       break;
676 
677     r                       = sscanf(buf, "%5s %d", &Triloops_184[6 * i], &Triloop_E37_184[i]);
678     Triloops_184[6 * i + 5] = ' ';
679     free(buf);
680     i++;
681   } while ((r == 2) && (i < 40));
682   return;
683 }
684 
685 
686 /*------------------------------------------------------------*/
687 
688 
689 PRIVATE void
ignore_comment(char * line)690 ignore_comment(char *line)
691 {
692   /* excise C style comments */
693   /* only one comment per line, no multiline comments */
694   char *cp1, *cp2;
695 
696   if ((cp1 = strstr(line, "/*"))) {
697     cp2 = strstr(cp1, "*/");
698     if (cp2 == NULL)
699       vrna_message_error("convert_epars: unclosed comment in parameter file");
700 
701     /* can't use strcpy for overlapping strings */
702     for (cp2 += 2; *cp2 != '\0'; cp2++, cp1++)
703       *cp1 = *cp2;
704     *cp1 = '\0';
705   }
706 
707   return;
708 }
709 
710 
711 PRIVATE enum parset_184
gettype_184(char ident[])712 gettype_184(char ident[])
713 {
714   if (strcmp(ident, "stack_enthalpies") == 0)
715     return SH_184;
716   else if (strcmp(ident, "stack_energies") == 0)
717     return S_184;
718   else if (strcmp(ident, "hairpin") == 0)
719     return HP_184;
720   else if (strcmp(ident, "bulge") == 0)
721     return B_184;
722   else if (strcmp(ident, "internal_loop") == 0)
723     return IL_184;
724   else if (strcmp(ident, "mismatch_hairpin") == 0)
725     return MMH_184;
726   else if (strcmp(ident, "mismatch_interior") == 0)
727     return MMI_184;
728   else if (strcmp(ident, "mismatch_multi") == 0)
729     return MMM_184;
730   else if (strcmp(ident, "mismatch_enthalpies") == 0)
731     return MM_H_184;
732   else if (strcmp(ident, "int11_energies") == 0)
733     return INT11_184;
734   else if (strcmp(ident, "int11_enthalpies") == 0)
735     return INT11_H_184;
736   else if (strcmp(ident, "int21_energies") == 0)
737     return INT21_184;
738   else if (strcmp(ident, "int21_enthalpies") == 0)
739     return INT21_H_184;
740   else if (strcmp(ident, "int22_energies") == 0)
741     return INT22_184;
742   else if (strcmp(ident, "int22_enthalpies") == 0)
743     return INT22_H_184;
744   else if (strcmp(ident, "dangle5") == 0)
745     return DE5_184;
746   else if (strcmp(ident, "dangle3") == 0)
747     return DE3_184;
748   else if (strcmp(ident, "dangle5_enthalpies") == 0)
749     return DE5_H_184;
750   else if (strcmp(ident, "dangle3_enthalpies") == 0)
751     return DE3_H_184;
752   else if (strcmp(ident, "ML_params") == 0)
753     return ML_184;
754   else if (strcmp(ident, "NINIO") == 0)
755     return NIN_184;
756   else if (strcmp(ident, "Tetraloops") == 0)
757     return TL_184;
758   else if (strcmp(ident, "Triloops") == 0)
759     return TRI_184;
760   else if (strcmp(ident, "END") == 0)
761     return QUIT_184;
762   else
763     return UNKNOWN_184;
764 }
765 
766 
767 PRIVATE void
write_new_parameter_file(FILE * ofile,unsigned int option_bits)768 write_new_parameter_file(FILE         *ofile,
769                          unsigned int option_bits)
770 {
771   int           c;
772   char          *pnames[] = {
773     "NP", "CG", "GC", "GU", "UG", "AU", "UA", " @"
774   };
775   char          bnames[]  = "@ACGU";
776   unsigned int  options   = 0;
777 
778   options = (option_bits & VRNA_CONVERT_OUTPUT_ALL) ?
779             VRNA_CONVERT_OUTPUT_HP
780             | VRNA_CONVERT_OUTPUT_STACK
781             | VRNA_CONVERT_OUTPUT_MM_HP
782             | VRNA_CONVERT_OUTPUT_MM_INT
783             | VRNA_CONVERT_OUTPUT_MM_INT_1N
784             | VRNA_CONVERT_OUTPUT_MM_INT_23
785             | VRNA_CONVERT_OUTPUT_MM_MULTI
786             | VRNA_CONVERT_OUTPUT_MM_EXT
787             | VRNA_CONVERT_OUTPUT_DANGLE5
788             | VRNA_CONVERT_OUTPUT_DANGLE3
789             | VRNA_CONVERT_OUTPUT_INT_11
790             | VRNA_CONVERT_OUTPUT_INT_21
791             | VRNA_CONVERT_OUTPUT_INT_22
792             | VRNA_CONVERT_OUTPUT_BULGE
793             | VRNA_CONVERT_OUTPUT_INT
794             | VRNA_CONVERT_OUTPUT_ML
795             | VRNA_CONVERT_OUTPUT_MISC
796             | VRNA_CONVERT_OUTPUT_SPECIAL_HP
797             | VRNA_CONVERT_OUTPUT_NINIO
798             :
799             option_bits;
800 
801   make_pair_matrix(); /* needed for special loop energy contributions */
802 
803   fprintf(ofile, "## RNAfold parameter file v2.0\n");
804 
805   if (options & VRNA_CONVERT_OUTPUT_STACK) {
806     fprintf(ofile, "\n# %s\n", settype(S));
807     fprintf(ofile, "/*  CG    GC    GU    UG    AU    UA    @  */\n");
808     for (c = 1; c < NBPAIRS + 1; c++)
809       display_array(stack37_184[c] + 1, NBPAIRS, NBPAIRS, ofile);
810     fprintf(ofile, "\n# %s\n", settype(S_H));
811     fprintf(ofile, "/*  CG    GC    GU    UG    AU    UA    @  */\n");
812     for (c = 1; c < NBPAIRS + 1; c++)
813       display_array(enthalpies_184[c] + 1, NBPAIRS, NBPAIRS, ofile);
814   }
815 
816   if (options & VRNA_CONVERT_OUTPUT_MM_HP) {
817     fprintf(ofile, "\n# %s\n", settype(MMH));
818     {
819       int i, k;
820       for (k = 1; k < NBPAIRS + 1; k++)
821         for (i = 0; i < 5; i++)
822           display_array(mismatchH37_184[k][i], 5, 5, ofile);
823     }
824     fprintf(ofile, "\n# %s\n", settype(MMH_H));
825     {
826       int i, k;
827       for (k = 1; k < NBPAIRS + 1; k++)
828         for (i = 0; i < 5; i++)
829           display_array(mism_H_184[k][i], 5, 5, ofile);
830     }
831   }
832 
833   if (options & VRNA_CONVERT_OUTPUT_MM_INT) {
834     fprintf(ofile, "\n# %s\n", settype(MMI));
835     {
836       int i, k;
837       for (k = 1; k < NBPAIRS + 1; k++)
838         for (i = 0; i < 5; i++)
839           display_array(mismatchI37_184[k][i], 5, 5, ofile);
840     }
841     fprintf(ofile, "\n# %s\n", settype(MMI_H));
842     {
843       int i, k;
844       for (k = 1; k < NBPAIRS + 1; k++)
845         for (i = 0; i < 5; i++)
846           display_array(mism_H_184[k][i], 5, 5, ofile);
847     }
848   }
849 
850   if (options & VRNA_CONVERT_OUTPUT_MM_INT_1N) {
851     fprintf(ofile, "\n# %s\n", settype(MMI1N));
852     {
853       int i, k;
854       for (k = 1; k < NBPAIRS + 1; k++)
855         for (i = 0; i < 5; i++)
856           display_array(mismatchI37_184[k][i], 5, 5, ofile);
857     }
858     fprintf(ofile, "\n# %s\n", settype(MMI1N_H));
859     {
860       int i, k;
861       for (k = 1; k < NBPAIRS + 1; k++)
862         for (i = 0; i < 5; i++)
863           display_array(mism_H_184[k][i], 5, 5, ofile);
864     }
865   }
866 
867   if (options & VRNA_CONVERT_OUTPUT_MM_INT_23) {
868     fprintf(ofile, "\n# %s\n", settype(MMI23));
869     {
870       int i, k;
871       for (k = 1; k < NBPAIRS + 1; k++)
872         for (i = 0; i < 5; i++)
873           display_array(mismatchI37_184[k][i], 5, 5, ofile);
874     }
875     fprintf(ofile, "\n# %s\n", settype(MMI23_H));
876     {
877       int i, k;
878       for (k = 1; k < NBPAIRS + 1; k++)
879         for (i = 0; i < 5; i++)
880           display_array(mism_H_184[k][i], 5, 5, ofile);
881     }
882   }
883 
884   if (options & VRNA_CONVERT_OUTPUT_MM_MULTI) {
885     fprintf(ofile, "\n# %s\n", settype(MMM));
886     fprintf(ofile, "/*  @     A     C     G     U   */\n");
887     {
888       int i, j, k;
889       int bla[5];
890       for (k = 1; k < NBPAIRS + 1; k++)
891         for (i = 0; i < 5; i++) {
892           for (j = 0; j < 5; j++)
893             bla[j] =
894               ((dangle5_37_184[k][i] ==
895                 INF) ? 0 : dangle5_37_184[k][i]) +
896               ((dangle3_37_184[k][j] == INF) ? 0 : dangle3_37_184[k][j]);
897           display_array(bla, 5, 5, ofile);
898         }
899     }
900     fprintf(ofile, "\n# %s\n", settype(MMM_H));
901     fprintf(ofile, "/*  @     A     C     G     U   */\n");
902     {
903       int i, j, k, bla[5];
904       for (k = 1; k < NBPAIRS + 1; k++)
905         for (i = 0; i < 5; i++) {
906           for (j = 0; j < 5; j++)
907             bla[j] =
908               ((dangle5_H_184[k][i] ==
909                 INF) ? 0 : dangle5_H_184[k][i]) +
910               ((dangle3_H_184[k][j] == INF) ? 0 : dangle3_H_184[k][j]);
911           display_array(bla, 5, 5, ofile);
912         }
913     }
914   }
915 
916   if (options & VRNA_CONVERT_OUTPUT_MM_EXT) {
917     fprintf(ofile, "\n# %s\n", settype(MME));
918     fprintf(ofile, "/*  @     A     C     G     U   */\n");
919     {
920       int i, j, k;
921       int bla[5];
922       for (k = 1; k < NBPAIRS + 1; k++)
923         for (i = 0; i < 5; i++) {
924           for (j = 0; j < 5; j++)
925             bla[j] =
926               ((dangle5_37_184[k][i] ==
927                 INF) ? 0 : dangle5_37_184[k][i]) +
928               ((dangle3_37_184[k][j] == INF) ? 0 : dangle3_37_184[k][j]);
929           display_array(bla, 5, 5, ofile);
930         }
931     }
932     fprintf(ofile, "\n# %s\n", settype(MME_H));
933     fprintf(ofile, "/*  @     A     C     G     U   */\n");
934     {
935       int i, j, k, bla[5];
936       for (k = 1; k < NBPAIRS + 1; k++)
937         for (i = 0; i < 5; i++) {
938           for (j = 0; j < 5; j++)
939             bla[j] =
940               ((dangle5_37_184[k][i] ==
941                 INF) ? 0 : dangle5_H_184[k][i]) +
942               ((dangle3_H_184[k][j] == INF) ? 0 : dangle3_H_184[k][j]);
943           display_array(bla, 5, 5, ofile);
944         }
945     }
946   }
947 
948   if (options & VRNA_CONVERT_OUTPUT_DANGLE5) {
949     fprintf(ofile, "\n# %s\n", settype(D5));
950     fprintf(ofile, "/*  @     A     C     G     U   */\n");
951     for (c = 1; c < NBPAIRS + 1; c++)
952       display_array(dangle5_37_184[c], 5, 5, ofile);
953     fprintf(ofile, "\n# %s\n", settype(D5_H));
954     fprintf(ofile, "/*  @     A     C     G     U   */\n");
955     for (c = 1; c < NBPAIRS + 1; c++)
956       display_array(dangle5_H_184[c], 5, 5, ofile);
957   }
958 
959   if (options & VRNA_CONVERT_OUTPUT_DANGLE3) {
960     fprintf(ofile, "\n# %s\n", settype(D3));
961     fprintf(ofile, "/*  @     A     C     G     U   */\n");
962     for (c = 1; c < NBPAIRS + 1; c++)
963       display_array(dangle3_37_184[c], 5, 5, ofile);
964     fprintf(ofile, "\n# %s\n", settype(D3_H));
965     fprintf(ofile, "/*  @     A     C     G     U   */\n");
966     for (c = 1; c < NBPAIRS + 1; c++)
967       display_array(dangle3_H_184[c], 5, 5, ofile);
968   }
969 
970   if (options & VRNA_CONVERT_OUTPUT_INT_11) {
971     /* don't print "no pair" entries for interior loop arrays */
972     fprintf(ofile, "\n# %s\n", settype(INT11));
973     {
974       int i, k, l;
975       for (k = 1; k < NBPAIRS + 1; k++)
976         for (l = 1; l < NBPAIRS + 1; l++) {
977           fprintf(ofile, "/* %2s..%2s */\n", pnames[k], pnames[l]);
978           for (i = 0; i < 5; i++)
979             display_array(int11_37_184[k][l][i], 5, 5, ofile);
980         }
981     }
982     fprintf(ofile, "\n# %s\n", settype(INT11_H));
983     {
984       int i, k, l;
985       for (k = 1; k < NBPAIRS + 1; k++)
986         for (l = 1; l < NBPAIRS + 1; l++) {
987           fprintf(ofile, "/* %2s..%2s */\n", pnames[k], pnames[l]);
988           for (i = 0; i < 5; i++)
989             display_array(int11_H_184[k][l][i], 5, 5, ofile);
990         }
991     }
992   }
993 
994   if (options & VRNA_CONVERT_OUTPUT_INT_21) {
995     fprintf(ofile, "\n# %s\n", settype(INT21));
996     {
997       int p1, p2, i, j;
998       for (p1 = 1; p1 < NBPAIRS + 1; p1++)
999         for (p2 = 1; p2 < NBPAIRS + 1; p2++)
1000           for (i = 0; i < 5; i++) {
1001             fprintf(ofile, "/* %2s.%c..%2s */\n", pnames[p1], bnames[i], pnames[p2]);
1002             for (j = 0; j < 5; j++)
1003               display_array(int21_37_184[p1][p2][i][j], 5, 5, ofile);
1004           }
1005     }
1006     fprintf(ofile, "\n# %s\n", settype(INT21_H));
1007     {
1008       int p1, p2, i, j;
1009       for (p1 = 1; p1 < NBPAIRS + 1; p1++)
1010         for (p2 = 1; p2 < NBPAIRS + 1; p2++)
1011           for (i = 0; i < 5; i++) {
1012             fprintf(ofile, "/* %2s.%c..%2s */\n", pnames[p1], bnames[i], pnames[p2]);
1013             for (j = 0; j < 5; j++)
1014               display_array(int21_H_184[p1][p2][i][j], 5, 5, ofile);
1015           }
1016     }
1017   }
1018 
1019   if (options & VRNA_CONVERT_OUTPUT_INT_22) {
1020     fprintf(ofile, "\n# %s\n", settype(INT22));
1021     {
1022       int p1, p2, i, j, k;
1023       for (p1 = 1; p1 < NBPAIRS; p1++)
1024         for (p2 = 1; p2 < NBPAIRS; p2++)
1025           for (i = 1; i < 5; i++)
1026             for (j = 1; j < 5; j++) {
1027               fprintf(ofile, "/* %2s.%c%c..%2s */\n", pnames[p1], bnames[i], bnames[j], pnames[p2]);
1028               for (k = 1; k < 5; k++)
1029                 display_array(int22_37_184[p1][p2][i][j][k] + 1, 4, 5, ofile);
1030             }
1031     }
1032     fprintf(ofile, "\n# %s\n", settype(INT22_H));
1033     {
1034       int p1, p2, i, j, k;
1035       for (p1 = 1; p1 < NBPAIRS; p1++)
1036         for (p2 = 1; p2 < NBPAIRS; p2++)
1037           for (i = 1; i < 5; i++)
1038             for (j = 1; j < 5; j++) {
1039               fprintf(ofile, "/* %2s.%c%c..%2s */\n", pnames[p1], bnames[i], bnames[j], pnames[p2]);
1040               for (k = 1; k < 5; k++)
1041                 display_array(int22_H_184[p1][p2][i][j][k] + 1, 4, 5, ofile);
1042             }
1043     }
1044   }
1045 
1046   if (options & VRNA_CONVERT_OUTPUT_HP) {
1047     fprintf(ofile, "\n# %s\n", settype(HP));
1048     display_array(hairpin37_184, 31, 10, ofile);
1049     /* we had no hairpin enthalpies before, so
1050      *  we just pretend to have had some with value 0
1051      */
1052     fprintf(ofile, "\n# %s\n", settype(HP_H));
1053     {
1054       fprintf(ofile, "   INF   INF   INF");
1055       for (c = 4; c <= 31; c++) {
1056         fprintf(ofile, "%6d", 0);
1057         if (c % 10 == 0)
1058           fprintf(ofile, "\n");
1059       }
1060     }
1061     fprintf(ofile, "\n");
1062   }
1063 
1064   if (options & VRNA_CONVERT_OUTPUT_BULGE) {
1065     fprintf(ofile, "\n# %s\n", settype(B));
1066     display_array(bulge37_184, 31, 10, ofile);
1067 
1068     /* we had no bulge enthalpies before, so
1069      *  we just pretend to have had some with value 0
1070      */
1071     fprintf(ofile, "\n# %s\n", settype(B_H));
1072     {
1073       fprintf(ofile, "   INF");
1074       for (c = 2; c <= 31; c++) {
1075         fprintf(ofile, "%6d", 0);
1076         if (c % 10 == 0)
1077           fprintf(ofile, "\n");
1078       }
1079     }
1080     fprintf(ofile, "\n");
1081   }
1082 
1083   if (options & VRNA_CONVERT_OUTPUT_INT) {
1084     fprintf(ofile, "\n# %s\n", settype(IL));
1085     display_array(internal_loop37_184, 31, 10, ofile);
1086 
1087     /* we had no internal_loop enthalpies before, so
1088      *  we just pretend to have had some with value 0
1089      */
1090     fprintf(ofile, "\n# %s\n", settype(IL_H));
1091     {
1092       fprintf(ofile, "   INF   INF   INF   INF");
1093       for (c = 5; c <= 31; c++) {
1094         fprintf(ofile, "%6d", 0);
1095         if (c % 10 == 0)
1096           fprintf(ofile, "\n");
1097       }
1098     }
1099     fprintf(ofile, "\n");
1100     fprintf(ofile, "\n# %s\n"
1101             "/* Ninio = MIN(max, m*|n1-n2| */\n"
1102             "/*\t    m\t  m_dH     max  */\n"
1103             "\t%6d\t%6d\t%6d\n", settype(NIN), F_ninio37_184[2], 0, MAX_NINIO_184);
1104   }
1105 
1106   if (options & VRNA_CONVERT_OUTPUT_ML) {
1107     fprintf(ofile, "\n# %s\n", settype(ML));
1108     fprintf(ofile, "/* F = cu*n_unpaired + cc + ci*loop_degree (+TermAU) */\n");
1109     fprintf(ofile, "/*\t    cu\t cu_dH\t    cc\t cc_dH\t    ci\t ci_dH  */\n");
1110     fprintf(ofile,
1111             "\t%6d\t%6d\t%6d\t%6d\t%6d\t%6d\n",
1112             ML_BASE37_184,
1113             0,
1114             ML_closing37_184,
1115             0,
1116             ML_intern37_184,
1117             0);
1118   }
1119 
1120   if (options & VRNA_CONVERT_OUTPUT_MISC) {
1121     fprintf(ofile, "\n# %s\n", settype(MISC));
1122     fprintf(ofile, "/* all parameters are pairs of 'energy enthalpy' */\n");
1123     fprintf(ofile, "/*    DuplexInit     TerminalAU   LXC  */\n");
1124     fprintf(ofile,
1125             "   %6d %6d %6d %6d   %3.6f %6d\n",
1126             DuplexInit_184,
1127             0,
1128             TerminalAU_184,
1129             0,
1130             lxc37_184,
1131             0);
1132   }
1133 
1134   if (options & VRNA_CONVERT_OUTPUT_SPECIAL_HP) {
1135     fprintf(ofile, "\n# %s\n", settype(TRI));
1136     {
1137       int base_en = hairpin37_184[3];
1138       int base_dH = TETRA_ENTH37_184;
1139       for (c = 0; c < (int)strlen(Triloops_184) / 6; c++) {
1140         int   en = base_en;
1141         char  bla[5];
1142         strncpy(bla, Triloops_184 + c * 6, 5);
1143         int   type = pair[(short)encode_char(toupper(bla[0]))][(short)encode_char(toupper(bla[4]))];
1144         if (type > 2)
1145           en += TerminalAU_184;
1146 
1147         fprintf(ofile, "\t%.5s %6d %6d\n", Triloops_184 + c * 6, Triloop_E37_184[c] + en, base_dH);
1148       }
1149     }
1150 
1151     /* since the old hairpin loop function treated the tabulated tetraloop energy as bonus
1152      *  and the new one takes this tabulated energy as a total energy, we have to compute some
1153      *  things now...
1154      */
1155     fprintf(ofile, "\n# %s\n", settype(TL));
1156     {
1157       int base_en = hairpin37_184[4];
1158       int base_dH = TETRA_ENTH37_184;
1159       for (c = 0; c < (int)strlen(Tetraloops_184) / 7; c++) {
1160         char  bla[6];
1161         int   en  = base_en;
1162         int   dH  = base_dH;
1163         strncpy(bla, Tetraloops_184 + c * 7, 6);
1164         short si    = (short)encode_char(toupper(bla[1]));
1165         short sj    = (short)encode_char(toupper(bla[4]));
1166         int   type  =
1167           pair[(short)encode_char(toupper(bla[0]))][(short)encode_char(toupper(bla[5]))];
1168         en  += mismatchH37_184[type][si][sj];
1169         dH  += mism_H_184[type][si][sj];
1170         fprintf(ofile, "\t%.6s %6d %6d\n", Tetraloops_184 + c * 7, en + TETRA_ENERGY37_184[c], dH);
1171       }
1172     }
1173     fprintf(ofile, "\n# %s\n", settype(HEX));
1174     {
1175       fprintf(ofile, "\n");
1176     }
1177   }
1178 
1179   fprintf(ofile, "\n# %s\n", settype(QUIT));
1180 }
1181 
1182 
1183 PRIVATE void
check_symmetry(void)1184 check_symmetry(void)
1185 {
1186   int i, j, k, l;
1187 
1188   for (i = 0; i <= NBPAIRS; i++)
1189     for (j = 0; j <= NBPAIRS; j++)
1190       if (stack37_184[i][j] != stack37_184[j][i])
1191         vrna_message_warning("stacking energies not symmetric");
1192 
1193   for (i = 0; i <= NBPAIRS; i++)
1194     for (j = 0; j <= NBPAIRS; j++)
1195       if (enthalpies_184[i][j] != enthalpies_184[j][i])
1196         vrna_message_warning("stacking enthalpies not symmetric");
1197 
1198   /* interior 1x1 loops */
1199   for (i = 0; i <= NBPAIRS; i++)
1200     for (j = 0; j <= NBPAIRS; j++)
1201       for (k = 0; k < 5; k++)
1202         for (l = 0; l < 5; l++)
1203           if (int11_37_184[i][j][k][l] != int11_37_184[j][i][l][k])
1204             vrna_message_warning("int11 energies not symmetric");
1205 
1206   for (i = 0; i <= NBPAIRS; i++)
1207     for (j = 0; j <= NBPAIRS; j++)
1208       for (k = 0; k < 5; k++)
1209         for (l = 0; l < 5; l++)
1210           if (int11_H_184[i][j][k][l] != int11_H_184[j][i][l][k])
1211             vrna_message_warning("int11 enthalpies not symmetric");
1212 
1213   /* interior 2x2 loops */
1214   for (i = 0; i <= NBPAIRS; i++)
1215     for (j = 0; j <= NBPAIRS; j++)
1216       for (k = 0; k < 5; k++)
1217         for (l = 0; l < 5; l++) {
1218           int m, n;
1219           for (m = 0; m < 5; m++)
1220             for (n = 0; n < 5; n++)
1221               if (int22_37_184[i][j][k][l][m][n] != int22_37_184[j][i][m][n][k][l])
1222                 vrna_message_warning("int22 energies not symmetric");
1223         }
1224 
1225   for (i = 0; i <= NBPAIRS; i++)
1226     for (j = 0; j <= NBPAIRS; j++)
1227       for (k = 0; k < 5; k++)
1228         for (l = 0; l < 5; l++) {
1229           int m, n;
1230           for (m = 0; m < 5; m++)
1231             for (n = 0; n < 5; n++)
1232               if (int22_H_184[i][j][k][l][m][n] != int22_H_184[j][i][m][n][k][l]) {
1233                 vrna_message_warning("int22 enthalpies not symmetric: %d %d %d %d %d %d",
1234                                      i,
1235                                      j,
1236                                      k,
1237                                      l,
1238                                      m,
1239                                      n);
1240               }
1241         }
1242 }
1243