RNAlib-2.4.0
interior_loops.h
Go to the documentation of this file.
1 #ifndef VIENNA_RNA_PACKAGE_INTERIOR_LOOPS_H
2 #define VIENNA_RNA_PACKAGE_INTERIOR_LOOPS_H
3 
4 #include <ViennaRNA/utils.h>
5 #include "ViennaRNA/energy_par.h"
7 #include <ViennaRNA/params.h>
9 
10 #ifdef __GNUC__
11 # define INLINE inline
12 #else
13 # define INLINE
14 #endif
15 
16 #ifdef ON_SAME_STRAND
17 #undef ON_SAME_STRAND
18 #endif
19 
20 #define ON_SAME_STRAND(I, J, C) (((I) >= (C)) || ((J) < (C)))
21 
77 PRIVATE INLINE int E_IntLoop(int n1,
78  int n2,
79  int type,
80  int type_2,
81  int si1,
82  int sj1,
83  int sp1,
84  int sq1,
85  vrna_param_t *P);
86 
87 
107 PRIVATE INLINE FLT_OR_DBL exp_E_IntLoop(int u1,
108  int u2,
109  int type,
110  int type2,
111  short si1,
112  short sj1,
113  short sp1,
114  short sq1,
115  vrna_exp_param_t *P);
116 
117 
118 PRIVATE INLINE int E_IntLoop_Co(int type,
119  int type_2,
120  int i,
121  int j,
122  int p,
123  int q,
124  int cutpoint,
125  short si1,
126  short sj1,
127  short sp1,
128  short sq1,
129  int dangles,
130  vrna_param_t *P);
131 
132 
133 /*
134  #################################
135  # BEGIN OF FUNCTION DEFINITIONS #
136  #################################
137  */
138 
139 /*
140  * ugly but fast interior loop evaluation
141  *
142  * Avoid including this function in your own code. It only serves
143  * as a fast inline block internally re-used throughout the RNAlib. It
144  * evalutes the free energy of interior loops in single sequences or sequence
145  * hybrids. Soft constraints are also applied if available.
146  *
147  * NOTE: do not include into doxygen reference manual!
148  */
149 PRIVATE INLINE int
150 ubf_eval_int_loop(int i,
151  int j,
152  int p,
153  int q,
154  int i1,
155  int j1,
156  int p1,
157  int q1,
158  short si,
159  short sj,
160  short sp,
161  short sq,
162  unsigned char type,
163  unsigned char type_2,
164  int *rtype,
165  int ij,
166  int cp,
167  vrna_param_t *P,
168  vrna_sc_t *sc)
169 {
170  int energy, u1, u2;
171 
172  u1 = p1 - i;
173  u2 = j1 - q;
174 
175  if ((cp < 0) || (ON_SAME_STRAND(i, p, cp) && ON_SAME_STRAND(q, j, cp))) {
176  /* regular interior loop */
177  energy = E_IntLoop(u1, u2, type, type_2, si, sj, sp, sq, P);
178  } else {
179  /* interior loop like cofold structure */
180  short Si, Sj;
181  Si = ON_SAME_STRAND(i, i1, cp) ? si : -1;
182  Sj = ON_SAME_STRAND(j1, j, cp) ? sj : -1;
183  energy = E_IntLoop_Co(rtype[type], rtype[type_2],
184  i, j, p, q,
185  cp,
186  Si, Sj,
187  sp, sq,
189  P);
190  }
191 
192  /* add soft constraints */
193  if (sc) {
194  if (sc->energy_up)
195  energy += sc->energy_up[i1][u1]
196  + sc->energy_up[q1][u2];
197 
198  if (sc->energy_bp)
199  energy += sc->energy_bp[ij];
200 
201  if (sc->energy_stack)
202  if (u1 + u2 == 0) {
203  int a = sc->energy_stack[i]
204  + sc->energy_stack[p]
205  + sc->energy_stack[q]
206  + sc->energy_stack[j];
207  energy += a;
208  }
209 
210  if (sc->f)
211  energy += sc->f(i, j, p, q, VRNA_DECOMP_PAIR_IL, sc->data);
212  }
213 
214  return energy;
215 }
216 
217 
218 /*
219  * ugly but fast exterior interior loop evaluation
220  *
221  * Avoid including this function in your own code. It only serves
222  * as a fast inline block internally re-used throughout the RNAlib. It
223  * evalutes the free energy of interior loops in single sequences or sequence
224  * hybrids. Soft constraints are also applied if available.
225  *
226  * NOTE: do not include into doxygen reference manual!
227  */
228 PRIVATE INLINE int
229 ubf_eval_ext_int_loop(int i,
230  int j,
231  int p,
232  int q,
233  int i1,
234  int j1,
235  int p1,
236  int q1,
237  short si,
238  short sj,
239  short sp,
240  short sq,
241  unsigned char type,
242  unsigned char type_2,
243  int length,
244  vrna_param_t *P,
245  vrna_sc_t *sc)
246 {
247  int energy, u1, u2, u3;
248 
249  u1 = i1;
250  u2 = p1 - j;
251  u3 = length - q;
252 
253  energy = E_IntLoop(u2, u1 + u3, type, type_2, si, sj, sp, sq, P);
254 
255  /* add soft constraints */
256  if (sc) {
257  if (sc->energy_up) {
258  energy += sc->energy_up[j1][u2]
259  + ((u3 > 0) ? sc->energy_up[q1][u3] : 0)
260  + ((u1 > 0) ? sc->energy_up[1][u1] : 0);
261  }
262 
263  if (sc->energy_stack)
264  if (u1 + u2 + u3 == 0)
265  energy += sc->energy_stack[i]
266  + sc->energy_stack[p]
267  + sc->energy_stack[q]
268  + sc->energy_stack[j];
269 
270  if (sc->f)
271  energy += sc->f(i, j, p, q, VRNA_DECOMP_PAIR_IL, sc->data);
272  }
273 
274  return energy;
275 }
276 
277 
278 PRIVATE INLINE int
279 E_IntLoop(int n1,
280  int n2,
281  int type,
282  int type_2,
283  int si1,
284  int sj1,
285  int sp1,
286  int sq1,
287  vrna_param_t *P)
288 {
289  /* compute energy of degree 2 loop (stack bulge or interior) */
290  int nl, ns, u, energy;
291 
292  energy = INF;
293 
294  if (n1 > n2) {
295  nl = n1;
296  ns = n2;
297  } else {
298  nl = n2;
299  ns = n1;
300  }
301 
302  if (nl == 0)
303  return P->stack[type][type_2]; /* stack */
304 
305  if (ns == 0) {
306  /* bulge */
307  energy = (nl <= MAXLOOP) ? P->bulge[nl] :
308  (P->bulge[30] + (int)(P->lxc * log(nl / 30.)));
309  if (nl == 1) {
310  energy += P->stack[type][type_2];
311  } else {
312  if (type > 2)
313  energy += P->TerminalAU;
314 
315  if (type_2 > 2)
316  energy += P->TerminalAU;
317  }
318 
319  return energy;
320  } else {
321  /* interior loop */
322  if (ns == 1) {
323  if (nl == 1) /* 1x1 loop */
324  return P->int11[type][type_2][si1][sj1];
325 
326  if (nl == 2) {
327  /* 2x1 loop */
328  if (n1 == 1)
329  energy = P->int21[type][type_2][si1][sq1][sj1];
330  else
331  energy = P->int21[type_2][type][sq1][si1][sp1];
332 
333  return energy;
334  } else {
335  /* 1xn loop */
336  energy =
337  (nl + 1 <=
338  MAXLOOP) ? (P->internal_loop[nl + 1]) : (P->internal_loop[30] +
339  (int)(P->lxc * log((nl + 1) / 30.)));
340  energy += MIN2(MAX_NINIO, (nl - ns) * P->ninio[2]);
341  energy += P->mismatch1nI[type][si1][sj1] + P->mismatch1nI[type_2][sq1][sp1];
342  return energy;
343  }
344  } else if (ns == 2) {
345  if (nl == 2) {
346  /* 2x2 loop */
347  return P->int22[type][type_2][si1][sp1][sq1][sj1];
348  } else if (nl == 3) {
349  /* 2x3 loop */
350  energy = P->internal_loop[5] + P->ninio[2];
351  energy += P->mismatch23I[type][si1][sj1] + P->mismatch23I[type_2][sq1][sp1];
352  return energy;
353  }
354  }
355 
356  {
357  /* generic interior loop (no else here!)*/
358  u = nl + ns;
359  energy =
360  (u <=
361  MAXLOOP) ? (P->internal_loop[u]) : (P->internal_loop[30] + (int)(P->lxc * log((u) / 30.)));
362 
363  energy += MIN2(MAX_NINIO, (nl - ns) * P->ninio[2]);
364 
365  energy += P->mismatchI[type][si1][sj1] + P->mismatchI[type_2][sq1][sp1];
366  }
367  }
368 
369  return energy;
370 }
371 
372 
373 PRIVATE INLINE FLT_OR_DBL
375  int u2,
376  int type,
377  int type2,
378  short si1,
379  short sj1,
380  short sp1,
381  short sq1,
382  vrna_exp_param_t *P)
383 {
384  int ul, us, no_close = 0;
385  double z = 0.;
386  int noGUclosure = P->model_details.noGUclosure;
387 
388  if ((noGUclosure) && ((type2 == 3) || (type2 == 4) || (type == 3) || (type == 4)))
389  no_close = 1;
390 
391  if (u1 > u2) {
392  ul = u1;
393  us = u2;
394  } else {
395  ul = u2;
396  us = u1;
397  }
398 
399  if (ul == 0) {
400  /* stack */
401  z = P->expstack[type][type2];
402  } else if (!no_close) {
403  if (us == 0) {
404  /* bulge */
405  z = P->expbulge[ul];
406  if (ul == 1) {
407  z *= P->expstack[type][type2];
408  } else {
409  if (type > 2)
410  z *= P->expTermAU;
411 
412  if (type2 > 2)
413  z *= P->expTermAU;
414  }
415 
416  return (FLT_OR_DBL)z;
417  } else if (us == 1) {
418  if (ul == 1) /* 1x1 loop */
419  return (FLT_OR_DBL)(P->expint11[type][type2][si1][sj1]);
420 
421  if (ul == 2) {
422  /* 2x1 loop */
423  if (u1 == 1)
424  return (FLT_OR_DBL)(P->expint21[type][type2][si1][sq1][sj1]);
425  else
426  return (FLT_OR_DBL)(P->expint21[type2][type][sq1][si1][sp1]);
427  } else {
428  /* 1xn loop */
429  z = P->expinternal[ul + us] * P->expmismatch1nI[type][si1][sj1] *
430  P->expmismatch1nI[type2][sq1][sp1];
431  return (FLT_OR_DBL)(z * P->expninio[2][ul - us]);
432  }
433  } else if (us == 2) {
434  if (ul == 2) {
435  /* 2x2 loop */
436  return (FLT_OR_DBL)(P->expint22[type][type2][si1][sp1][sq1][sj1]);
437  } else if (ul == 3) {
438  /* 2x3 loop */
439  z = P->expinternal[5] * P->expmismatch23I[type][si1][sj1] *
440  P->expmismatch23I[type2][sq1][sp1];
441  return (FLT_OR_DBL)(z * P->expninio[2][1]);
442  }
443  }
444 
445  /* generic interior loop (no else here!)*/
446  z = P->expinternal[ul + us] * P->expmismatchI[type][si1][sj1] *
447  P->expmismatchI[type2][sq1][sp1];
448  return (FLT_OR_DBL)(z * P->expninio[2][ul - us]);
449  }
450 
451  return (FLT_OR_DBL)z;
452 }
453 
454 
455 PRIVATE INLINE int
456 E_IntLoop_Co(int type,
457  int type_2,
458  int i,
459  int j,
460  int p,
461  int q,
462  int cutpoint,
463  short si1,
464  short sj1,
465  short sp1,
466  short sq1,
467  int dangles,
468  vrna_param_t *P)
469 {
470  int energy, ci, cj, cp, cq, d3, d5, d5_2, d3_2, tmm, tmm_2;
471 
472  energy = 0;
473  if (type > 2)
474  energy += P->TerminalAU;
475 
476  if (type_2 > 2)
477  energy += P->TerminalAU;
478 
479  if (!dangles)
480  return energy;
481 
482  ci = ON_SAME_STRAND(i, i + 1, cutpoint);
483  cj = ON_SAME_STRAND(j - 1, j, cutpoint);
484  cp = ON_SAME_STRAND(p - 1, p, cutpoint);
485  cq = ON_SAME_STRAND(q, q + 1, cutpoint);
486 
487  d3 = ci ? P->dangle3[type][si1] : 0;
488  d5 = cj ? P->dangle5[type][sj1] : 0;
489  d5_2 = cp ? P->dangle5[type_2][sp1] : 0;
490  d3_2 = cq ? P->dangle3[type_2][sq1] : 0;
491 
492  tmm = (cj && ci) ? P->mismatchExt[type][sj1][si1] : d5 + d3;
493  tmm_2 = (cp && cq) ? P->mismatchExt[type_2][sp1][sq1] : d5_2 + d3_2;
494 
495  if (dangles == 2)
496  return energy + tmm + tmm_2;
497 
498  /* now we may have non-double dangles only */
499  if (i + 2 < p) {
500  if (q + 2 < j)
501  energy += tmm + tmm_2;
502  else if (q + 2 == j)
503  energy += (cj && cq) ? MIN2(tmm + d5_2, tmm_2 + d3) : tmm + tmm_2;
504  else
505  energy += d3 + d5_2;
506  } else if (i + 2 == p) {
507  if (q + 2 < j)
508  energy += (ci && cp) ? MIN2(tmm + d3_2, tmm_2 + d5) : tmm + tmm_2;
509  else if (q + 2 == j)
510  energy += MIN2(tmm, MIN2(tmm_2, MIN2(d5 + d5_2, d3 + d3_2)));
511  else
512  energy += MIN2(d3, d5_2);
513  } else {
514  if (q + 2 < j)
515  energy += d5 + d3_2;
516  else if (q + 2 == j)
517  energy += MIN2(d5, d3_2);
518  }
519 
520  return energy;
521 }
522 
523 
524 int
525 vrna_E_int_loop(vrna_fold_compound_t *vc,
526  int i,
527  int j);
528 
529 
530 int
532  int i,
533  int j,
534  int k,
535  int l);
536 
537 
539 vrna_exp_E_int_loop(vrna_fold_compound_t *vc,
540  int i,
541  int j);
542 
543 
545 vrna_exp_E_interior_loop(vrna_fold_compound_t *vc,
546  int i,
547  int j,
548  int k,
549  int l);
550 
551 
552 int
553 vrna_E_ext_int_loop(vrna_fold_compound_t *vc,
554  int i,
555  int j,
556  int *ip,
557  int *iq);
558 
559 
560 int
561 vrna_E_stack(vrna_fold_compound_t *vc,
562  int i,
563  int j);
564 
565 
570 int
572  int *i,
573  int *j,
574  int *en,
575  vrna_bp_stack_t *bp_stack,
576  int *stack_count);
577 
578 
583 int
585  int *i,
586  int *j,
587  int en,
588  vrna_bp_stack_t *bp_stack,
589  int *stack_count);
590 
591 
597 #endif
int dangles
Specifies the dangle model used in any energy evaluation (0,1,2 or 3)
Definition: model.h:192
#define MAXLOOP
Definition: energy_const.h:29
vrna_md_t model_details
Model details to be used in the recursions.
Definition: params.h:95
vrna_md_t model_details
Model details to be used in the recursions.
Definition: params.h:151
double FLT_OR_DBL
Typename for floating point number in partition function computations.
Definition: data_structures.h:48
The most basic data structure required by many functions throughout the RNAlib.
Definition: data_structures.h:463
int noGUclosure
Do not allow loops to be closed by GU pair.
Definition: model.h:219
The datastructure that contains temperature scaled energy parameters.
Definition: params.h:57
int * energy_stack
Pseudo Energy contribution per base pair involved in a stack.
Definition: constraints_soft.h:186
vrna_callback_sc_energy * f
A function pointer used for pseudo energy contribution in MFE calculations.
Definition: constraints_soft.h:190
General utility- and helper-functions used throughout the ViennaRNA Package.
int vrna_eval_int_loop(vrna_fold_compound_t *vc, int i, int j, int k, int l)
Various data structures and pre-processor macros.
The soft constraints data structure.
Definition: constraints_soft.h:154
#define INF
Definition: energy_const.h:17
Functions to deal with sets of energy parameters.
The data structure that contains temperature scaled Boltzmann weights of the energy parameters...
Definition: params.h:101
int ** energy_up
Energy contribution for stretches of unpaired nucleotides.
Definition: constraints_soft.h:160
#define VRNA_DECOMP_PAIR_IL
Indicator for interior loop decomposition step.
Definition: constraints.h:72
Base pair stack element.
Definition: data_structures.h:229
Functions and data structures for constraining secondary structure predictions and evaluation...
int * energy_bp
Energy contribution for base pairs.
Definition: constraints_soft.h:171
int vrna_BT_stack(vrna_fold_compound_t *vc, int *i, int *j, int *en, vrna_bp_stack_t *bp_stack, int *stack_count)
Backtrack a stacked pair closed by .
PRIVATE int E_IntLoop(int n1, int n2, int type, int type_2, int si1, int sj1, int sp1, int sq1, vrna_param_t *P)
Definition: interior_loops.h:279
#define MIN2(A, B)
Get the minimum of two comparable values.
Definition: utils.h:116
int vrna_BT_int_loop(vrna_fold_compound_t *vc, int *i, int *j, int en, vrna_bp_stack_t *bp_stack, int *stack_count)
Backtrack an interior loop closed by .
int dangles
Switch the energy model for dangling end contributions (0, 1, 2, 3)
PRIVATE FLT_OR_DBL exp_E_IntLoop(int u1, int u2, int type, int type2, short si1, short sj1, short sp1, short sq1, vrna_exp_param_t *P)
Definition: interior_loops.h:374
void * data
A pointer to the data object provided for for pseudo energy contribution functions of the generic sof...
Definition: constraints_soft.h:207