interior_loops.h
Go to the documentation of this file.
#ifndef VIENNA_RNA_PACKAGE_INTERIOR_LOOPS_H
#define VIENNA_RNA_PACKAGE_INTERIOR_LOOPS_H
#include <ViennaRNA/utils.h>
#include "ViennaRNA/energy_par.h"
#include <ViennaRNA/data_structures.h>
#include <ViennaRNA/params.h>
#include <ViennaRNA/constraints.h>
#ifdef __GNUC__
# define INLINE inline
#else
# define INLINE
#endif
#ifdef ON_SAME_STRAND
#undef ON_SAME_STRAND
#endif
#define ON_SAME_STRAND(I,J,C) (((I)>=(C))||((J)<(C)))
PRIVATE INLINE int E_IntLoop(int n1,
int n2,
int type,
int type_2,
int si1,
int sj1,
int sp1,
int sq1,
vrna_param_t *P);
PRIVATE INLINE 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);
PRIVATE INLINE int E_IntLoop_Co(int type,
int type_2,
int i,
int j,
int p,
int q,
int cutpoint,
short si1,
short sj1,
short sp1,
short sq1,
int dangles,
vrna_param_t *P);
int E_stack(int i, int j, vrna_fold_compound_t *vc);
/*
#################################
# BEGIN OF FUNCTION DEFINITIONS #
#################################
*/
/*
* ugly but fast interior loop evaluation
*
* Avoid including this function in your own code. It only serves
* as a fast inline block internally re-used throughout the RNAlib. It
* evalutes the free energy of interior loops in single sequences or sequence
* hybrids. Soft constraints are also applied if available.
*
* NOTE: do not include into doxygen reference manual!
*/
PRIVATE INLINE int
ubf_eval_int_loop( int i,
int j,
int p,
int q,
int i1,
int j1,
int p1,
int q1,
short si,
short sj,
short sp,
short sq,
unsigned char type,
unsigned char type_2,
int *rtype,
int ij,
int cp,
vrna_param_t *P,
vrna_sc_t *sc){
int energy, u1, u2;
u1 = p1 - i;
u2 = j1 - q;
if((cp < 0) || (ON_SAME_STRAND(i, p, cp) && ON_SAME_STRAND(q, j, cp))){ /* regular interior loop */
energy = E_IntLoop(u1, u2, type, type_2, si, sj, sp, sq, P);
} else { /* interior loop like cofold structure */
short Si, Sj;
Si = ON_SAME_STRAND(i, i1, cp) ? si : -1;
Sj = ON_SAME_STRAND(j1, j, cp) ? sj : -1;
energy = E_IntLoop_Co(rtype[type], rtype[type_2],
i, j, p, q,
cp,
Si, Sj,
sp, sq,
P->model_details.dangles,
P);
}
/* add soft constraints */
if(sc){
if(sc->energy_up)
energy += sc->energy_up[i1][u1]
+ sc->energy_up[q1][u2];
if(sc->energy_bp)
energy += sc->energy_bp[ij];
if(sc->energy_stack)
if(u1 + u2 == 0){
int a = sc->energy_stack[i]
+ sc->energy_stack[p]
+ sc->energy_stack[q]
+ sc->energy_stack[j];
energy += a;
}
if(sc->f)
energy += sc->f(i, j, p, q, VRNA_DECOMP_PAIR_IL, sc->data);
}
return energy;
}
/*
* ugly but fast exterior interior loop evaluation
*
* Avoid including this function in your own code. It only serves
* as a fast inline block internally re-used throughout the RNAlib. It
* evalutes the free energy of interior loops in single sequences or sequence
* hybrids. Soft constraints are also applied if available.
*
* NOTE: do not include into doxygen reference manual!
*/
PRIVATE INLINE int
ubf_eval_ext_int_loop(int i,
int j,
int p,
int q,
int i1,
int j1,
int p1,
int q1,
short si,
short sj,
short sp,
short sq,
unsigned char type,
unsigned char type_2,
int length,
vrna_param_t *P,
vrna_sc_t *sc){
int energy, u1, u2, u3;
u1 = i1;
u2 = p1 - j;
u3 = length - q;
energy = E_IntLoop(u2, u1 + u3, type, type_2, si, sj, sp, sq, P);
/* add soft constraints */
if(sc){
if(sc->energy_up)
energy += sc->energy_up[j1][u2]
+ sc->energy_up[q1][u3]
+ sc->energy_up[1][u1];
if(sc->energy_stack)
if(u1 + u2 + u3 == 0)
energy += sc->energy_stack[i]
+ sc->energy_stack[p]
+ sc->energy_stack[q]
+ sc->energy_stack[j];
if(sc->f)
energy += sc->f(i, j, p, q, VRNA_DECOMP_PAIR_IL, sc->data);
}
return energy;
}
PRIVATE INLINE int
E_IntLoop(int n1,
int n2,
int type,
int type_2,
int si1,
int sj1,
int sp1,
int sq1,
vrna_param_t *P){
/* compute energy of degree 2 loop (stack bulge or interior) */
int nl, ns, u, energy;
energy = INF;
if (n1>n2) { nl=n1; ns=n2;}
else {nl=n2; ns=n1;}
if (nl == 0)
return P->stack[type][type_2]; /* stack */
if (ns==0) { /* bulge */
energy = (nl<=MAXLOOP)?P->bulge[nl]:
(P->bulge[30]+(int)(P->lxc*log(nl/30.)));
if (nl==1) energy += P->stack[type][type_2];
else {
if (type>2) energy += P->TerminalAU;
if (type_2>2) energy += P->TerminalAU;
}
return energy;
}
else { /* interior loop */
if (ns==1) {
if (nl==1) /* 1x1 loop */
return P->int11[type][type_2][si1][sj1];
if (nl==2) { /* 2x1 loop */
if (n1==1)
energy = P->int21[type][type_2][si1][sq1][sj1];
else
energy = P->int21[type_2][type][sq1][si1][sp1];
return energy;
}
else { /* 1xn loop */
energy = (nl+1<=MAXLOOP)?(P->internal_loop[nl+1]) : (P->internal_loop[30]+(int)(P->lxc*log((nl+1)/30.)));
energy += MIN2(MAX_NINIO, (nl-ns)*P->ninio[2]);
energy += P->mismatch1nI[type][si1][sj1] + P->mismatch1nI[type_2][sq1][sp1];
return energy;
}
}
else if (ns==2) {
if(nl==2) { /* 2x2 loop */
return P->int22[type][type_2][si1][sp1][sq1][sj1];}
else if (nl==3){ /* 2x3 loop */
energy = P->internal_loop[5]+P->ninio[2];
energy += P->mismatch23I[type][si1][sj1] + P->mismatch23I[type_2][sq1][sp1];
return energy;
}
}
{ /* generic interior loop (no else here!)*/
u = nl + ns;
energy = (u <= MAXLOOP) ? (P->internal_loop[u]) : (P->internal_loop[30]+(int)(P->lxc*log((u)/30.)));
energy += MIN2(MAX_NINIO, (nl-ns)*P->ninio[2]);
energy += P->mismatchI[type][si1][sj1] + P->mismatchI[type_2][sq1][sp1];
}
}
return energy;
}
PRIVATE INLINE 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){
int ul, us, no_close = 0;
double z = 0.;
if ((no_closingGU) && ((type2==3)||(type2==4)||(type==3)||(type==4)))
no_close = 1;
if (u1>u2) { ul=u1; us=u2;}
else {ul=u2; us=u1;}
if (ul==0) /* stack */
z = P->expstack[type][type2];
else if(!no_close){
if (us==0) { /* bulge */
z = P->expbulge[ul];
if (ul==1) z *= P->expstack[type][type2];
else {
if (type>2) z *= P->expTermAU;
if (type2>2) z *= P->expTermAU;
}
return (FLT_OR_DBL)z;
}
else if (us==1) {
if (ul==1){ /* 1x1 loop */
return (FLT_OR_DBL)(P->expint11[type][type2][si1][sj1]);
}
if (ul==2) { /* 2x1 loop */
if (u1==1)
return (FLT_OR_DBL)(P->expint21[type][type2][si1][sq1][sj1]);
else
return (FLT_OR_DBL)(P->expint21[type2][type][sq1][si1][sp1]);
}
else { /* 1xn loop */
z = P->expinternal[ul+us] * P->expmismatch1nI[type][si1][sj1] * P->expmismatch1nI[type2][sq1][sp1];
return (FLT_OR_DBL)(z * P->expninio[2][ul-us]);
}
}
else if (us==2) {
if(ul==2) /* 2x2 loop */
return (FLT_OR_DBL)(P->expint22[type][type2][si1][sp1][sq1][sj1]);
else if(ul==3){ /* 2x3 loop */
z = P->expinternal[5]*P->expmismatch23I[type][si1][sj1]*P->expmismatch23I[type2][sq1][sp1];
return (FLT_OR_DBL)(z * P->expninio[2][1]);
}
}
/* generic interior loop (no else here!)*/
z = P->expinternal[ul+us] * P->expmismatchI[type][si1][sj1] * P->expmismatchI[type2][sq1][sp1];
return (FLT_OR_DBL)(z * P->expninio[2][ul-us]);
}
return (FLT_OR_DBL)z;
}
PRIVATE INLINE int
E_IntLoop_Co( int type,
int type_2,
int i,
int j,
int p,
int q,
int cutpoint,
short si1,
short sj1,
short sp1,
short sq1,
int dangles,
vrna_param_t *P){
int energy, ci, cj, cp, cq, d3, d5, d5_2, d3_2, tmm, tmm_2;
energy = 0;
if(type > 2) energy += P->TerminalAU;
if(type_2 > 2) energy += P->TerminalAU;
if(!dangles) return energy;
ci = ON_SAME_STRAND(i, i + 1, cutpoint);
cj = ON_SAME_STRAND(j - 1, j, cutpoint);
cp = ON_SAME_STRAND(p - 1, p, cutpoint);
cq = ON_SAME_STRAND(q, q + 1, cutpoint);
d3 = ci ? P->dangle3[type][si1] : 0;
d5 = cj ? P->dangle5[type][sj1] : 0;
d5_2 = cp ? P->dangle5[type_2][sp1] : 0;
d3_2 = cq ? P->dangle3[type_2][sq1] : 0;
tmm = (cj && ci) ? P->mismatchExt[type][sj1][si1] : d5 + d3;
tmm_2 = (cp && cq) ? P->mismatchExt[type_2][sp1][sq1] : d5_2 + d3_2;
if(dangles == 2) return energy + tmm + tmm_2;
/* now we may have non-double dangles only */
if(i+2 < p){
if(q+2 < j){ energy += tmm + tmm_2;}
else if(q+2 == j){ energy += (cj && cq) ? MIN2(tmm + d5_2, tmm_2 + d3) : tmm + tmm_2;}
else energy += d3 + d5_2;
}
else if(i+2 == p){
if(q+2 < j){ energy += (ci && cp) ? MIN2(tmm + d3_2, tmm_2 + d5) : tmm + tmm_2;}
else if(q+2 == j){
energy += MIN2(tmm, MIN2(tmm_2, MIN2(d5 + d5_2, d3 + d3_2)));
}
else energy += MIN2(d3, d5_2);
}
else{
if(q+2 < j){ energy += d5 + d3_2;}
else if(q+2 == j){ energy += MIN2(d5, d3_2);}
}
return energy;
}
int
vrna_E_int_loop(vrna_fold_compound_t *vc,
int i,
int j);
PUBLIC FLT_OR_DBL
vrna_exp_E_int_loop(vrna_fold_compound_t *vc,
int i,
int j);
int
vrna_E_ext_int_loop(vrna_fold_compound_t *vc,
int i,
int j,
int *ip,
int *iq);
int
vrna_E_stack( vrna_fold_compound_t *vc,
int i,
int j);
int
E_IntLoop(int n1,
int n2,
int type,
int type_2,
int si1,
int sj1,
int sp1,
int sq1,
vrna_param_t *P);
PUBLIC 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);
int
E_IntLoop_Co( int type,
int type_2,
int i,
int j,
int p,
int q,
int cutpoint,
short si1,
short sj1,
short sp1,
short sq1,
int dangles,
vrna_param_t *P);
int
vrna_BT_stack(vrna_fold_compound_t *vc,
int *i,
int *j,
int *en,
vrna_bp_stack_t *bp_stack,
int *stack_count);
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);
#endif
E_IntLoop
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:277
MAXLOOP
#define MAXLOOP
Definition: energy_const.h:28
vrna_param_s::model_details
vrna_md_t model_details
Model details to be used in the recursions.
Definition: params.h:88
FLT_OR_DBL
double FLT_OR_DBL
Typename for floating point number in partition function computations.
Definition: data_structures.h:39
vrna_fc_s
The most basic data structure required by many functions throughout the RNAlib.
Definition: data_structures.h:390
vrna_param_s
The datastructure that contains temperature scaled energy parameters.
Definition: params.h:50
vrna_sc_s::energy_stack
int * energy_stack
Pseudo Energy contribution per base pair involved in a stack.
Definition: constraints_soft.h:117
MIN2
#define MIN2(A, B)
Get the minimum of two comparable values.
Definition: utils.h:112
exp_E_IntLoop
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:348
vrna_sc_s::f
vrna_callback_sc_energy * f
A function pointer used for pseudo energy contribution in MFE calculations.
Definition: constraints_soft.h:121
utils.h
General utility- and helper-functions used throughout the ViennaRNA Package.
data_structures.h
vrna_sc_s
The soft constraints data structure.
Definition: constraints_soft.h:111
INF
#define INF
Definition: energy_const.h:16
params.h
vrna_exp_param_s
The datastructure that contains temperature scaled Boltzmann weights of the energy parameters...
Definition: params.h:94
vrna_sc_s::energy_up
int ** energy_up
Energy contribution for stretches of unpaired nucleotides.
Definition: constraints_soft.h:112
VRNA_DECOMP_PAIR_IL
#define VRNA_DECOMP_PAIR_IL
Indicator for interior loop decomposition step.
Definition: constraints.h:80
vrna_md_s::dangles
int dangles
Specifies the dangle model used in any energy evaluation (0,1,2 or 3)
Definition: model.h:190
vrna_bp_stack_s
Base pair stack element.
Definition: data_structures.h:192
constraints.h
Functions and data structures for constraining secondary structure predictions and evaluation...
vrna_sc_s::energy_bp
int * energy_bp
Energy contribution for base pairs.
Definition: constraints_soft.h:113
vrna_BT_stack
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 .
no_closingGU
int no_closingGU
GU allowed only inside stacks if set to 1.
vrna_BT_int_loop
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 .
E_stack
int E_stack(int i, int j, vrna_fold_compound_t *vc)
Evaluate energy of a base pair stack closed by (i,j)
dangles
int dangles
Switch the energy model for dangling end contributions (0, 1, 2, 3)
vrna_sc_s::data
void * data
A pointer to the data object provided for for pseudo energy contribution functions of the generic sof...
Definition: constraints_soft.h:138