RNAlib-2.0.1
H/loop_energies.h
Go to the documentation of this file.
00001 #ifndef __VIENNA_RNA_PACKAGE_LOOP_ENERGIES_H__
00002 #define __VIENNA_RNA_PACKAGE_LOOP_ENERGIES_H__
00003 
00004 #include <stdio.h>
00005 #include <stdlib.h>
00006 #include <math.h>
00007 #include <ctype.h>
00008 #include <string.h>
00009 #include "params.h"
00010 #include "fold_vars.h"
00011 #include "energy_par.h"
00012 
00013 #ifdef __GNUC__
00014 # define INLINE inline
00015 #else
00016 # define INLINE
00017 #endif
00018 
00054 //#define E_MLstem(A,B,C,D)     E_Stem((A),(B),(C),0,(D))
00055 INLINE  PRIVATE int E_MLstem( int type,
00056                               int si1,
00057                               int sj1,
00058                               paramT *P);
00059 
00066 //#define exp_E_MLstem(A,B,C,D) exp_E_Stem((A),(B),(C),0,(D))
00067 INLINE  PRIVATE double exp_E_MLstem(int type,
00068                                     int si1,
00069                                     int sj1,
00070                                     pf_paramT *P);
00071 
00091 //#define E_ExtLoop(A,B,C,D)      E_Stem((A),(B),(C),1,(D))
00092 INLINE  PRIVATE int E_ExtLoop(int type,
00093                               int si1,
00094                               int sj1,
00095                               paramT *P);
00096 
00103 //#define exp_E_ExtLoop(A,B,C,D)  exp_E_Stem((A),(B),(C),1,(D))
00104 INLINE  PRIVATE double exp_E_ExtLoop( int type,
00105                                       int si1,
00106                                       int sj1,
00107                                       pf_paramT *P);
00108 
00153 INLINE  PRIVATE int E_IntLoop(int n1,
00154                               int n2,
00155                               int type,
00156                               int type_2,
00157                               int si1,
00158                               int sj1,
00159                               int sp1,
00160                               int sq1,
00161                               paramT *P);
00162 
00163 
00195 INLINE  PRIVATE int E_Hairpin(int size,
00196                               int type,
00197                               int si1,
00198                               int sj1,
00199                               const char *string,
00200                               paramT *P);
00201 
00247 INLINE  PRIVATE int E_Stem( int type,
00248                             int si1,
00249                             int sj1,
00250                             int extLoop,
00251                             paramT *P);
00252 
00261 INLINE  PRIVATE double exp_E_Stem(int type,
00262                                   int si1,
00263                                   int sj1,
00264                                   int extLoop,
00265                                   pf_paramT *P);
00266 
00284 INLINE  PRIVATE double exp_E_Hairpin( int u,
00285                                       int type,
00286                                       short si1,
00287                                       short sj1,
00288                                       const char *string,
00289                                       pf_paramT *P);
00290 
00310 INLINE  PRIVATE double  exp_E_IntLoop(int u1,
00311                                       int u2,
00312                                       int type,
00313                                       int type2,
00314                                       short si1,
00315                                       short sj1,
00316                                       short sp1,
00317                                       short sq1,
00318                                       pf_paramT *P);
00319 
00320 
00321 /*
00322 #################################
00323 # BEGIN OF FUNCTION DEFINITIONS #
00324 #################################
00325 */
00326 INLINE  PRIVATE int E_Hairpin(int size, int type, int si1, int sj1, const char *string, paramT *P){
00327   int energy;
00328 
00329   energy = (size <= 30) ? P->hairpin[size] : P->hairpin[30]+(int)(P->lxc*log((size)/30.));
00330   if (tetra_loop){
00331     if (size == 4) { /* check for tetraloop bonus */
00332       char tl[7]={0}, *ts;
00333       strncpy(tl, string, 6);
00334       if ((ts=strstr(P->Tetraloops, tl)))
00335         return (P->Tetraloop_E[(ts - P->Tetraloops)/7]);
00336     }
00337   }
00338   {
00339     if (size == 6) {
00340       char tl[9]={0}, *ts;
00341       strncpy(tl, string, 8);
00342       if ((ts=strstr(P->Hexaloops, tl)))
00343         return (energy = P->Hexaloop_E[(ts - P->Hexaloops)/9]);
00344     }
00345     if (size == 3) {
00346       char tl[6]={0,0,0,0,0,0}, *ts;
00347       strncpy(tl, string, 5);
00348       if ((ts=strstr(P->Triloops, tl))) {
00349         return (P->Triloop_E[(ts - P->Triloops)/6]);
00350       }
00351       return (energy + (type>2 ? P->TerminalAU : 0));
00352     }
00353   }
00354   energy += P->mismatchH[type][si1][sj1];
00355 
00356   return energy;
00357 }
00358 
00359 INLINE  PRIVATE int E_IntLoop(int n1, int n2, int type, int type_2, int si1, int sj1, int sp1, int sq1, paramT *P){
00360   /* compute energy of degree 2 loop (stack bulge or interior) */
00361   int nl, ns, energy;
00362 
00363   if (n1>n2) { nl=n1; ns=n2;}
00364   else {nl=n2; ns=n1;}
00365 
00366   if (nl == 0)
00367     return P->stack[type][type_2];  /* stack */
00368 
00369   if (ns==0) {                      /* bulge */
00370     energy = (nl<=MAXLOOP)?P->bulge[nl]:
00371       (P->bulge[30]+(int)(P->lxc*log(nl/30.)));
00372     if (nl==1) energy += P->stack[type][type_2];
00373     else {
00374       if (type>2) energy += P->TerminalAU;
00375       if (type_2>2) energy += P->TerminalAU;
00376     }
00377     return energy;
00378   }
00379   else {                            /* interior loop */
00380     if (ns==1) {
00381       if (nl==1)                    /* 1x1 loop */
00382         return P->int11[type][type_2][si1][sj1];
00383       if (nl==2) {                  /* 2x1 loop */
00384         if (n1==1)
00385           energy = P->int21[type][type_2][si1][sq1][sj1];
00386         else
00387           energy = P->int21[type_2][type][sq1][si1][sp1];
00388         return energy;
00389       }
00390       else {  /* 1xn loop */
00391         energy = (nl+1<=MAXLOOP)?(P->internal_loop[nl+1]) : (P->internal_loop[30]+(int)(P->lxc*log((nl+1)/30.)));
00392         energy += MIN2(MAX_NINIO, (nl-ns)*P->ninio[2]);
00393         energy += P->mismatch1nI[type][si1][sj1] + P->mismatch1nI[type_2][sq1][sp1];
00394         return energy;
00395       }
00396     }
00397     else if (ns==2) {
00398       if(nl==2)      {              /* 2x2 loop */
00399         return P->int22[type][type_2][si1][sp1][sq1][sj1];}
00400       else if (nl==3){              /* 2x3 loop */
00401         energy = P->internal_loop[5]+P->ninio[2];
00402         energy += P->mismatch23I[type][si1][sj1] + P->mismatch23I[type_2][sq1][sp1];
00403         return energy;
00404       }
00405 
00406     }
00407     { /* generic interior loop (no else here!)*/
00408       energy = (n1+n2<=MAXLOOP)?(P->internal_loop[n1+n2]) : (P->internal_loop[30]+(int)(P->lxc*log((n1+n2)/30.)));
00409 
00410       energy += MIN2(MAX_NINIO, (nl-ns)*P->ninio[2]);
00411 
00412       energy += P->mismatchI[type][si1][sj1] + P->mismatchI[type_2][sq1][sp1];
00413     }
00414   }
00415   return energy;
00416 }
00417 
00418 INLINE  PRIVATE int E_Stem(int type, int si1, int sj1, int extLoop, paramT *P){
00419   int energy = 0;
00420   int d5 = (si1 >= 0) ? P->dangle5[type][si1] : 0;
00421   int d3 = (sj1 >= 0) ? P->dangle3[type][sj1] : 0;
00422 
00423   if(type > 2)
00424     energy += P->TerminalAU;
00425 
00426   if(si1 >= 0 && sj1 >= 0)
00427     energy += (extLoop) ? P->mismatchExt[type][si1][sj1] : P->mismatchM[type][si1][sj1];
00428   else
00429     energy += d5 + d3;
00430 
00431   if(!extLoop) energy += P->MLintern[type];
00432   return energy;
00433 }
00434 
00435 INLINE  PRIVATE int E_ExtLoop(int type, int si1, int sj1, paramT *P){
00436   int energy = 0;
00437   if(si1 >= 0 && sj1 >= 0){
00438     energy += P->mismatchExt[type][si1][sj1];
00439   }
00440   else if (si1 >= 0){
00441     energy += P->dangle5[type][si1];
00442   }
00443   else if (sj1 >= 0){
00444     energy += P->dangle3[type][sj1];
00445   }
00446 
00447   if(type > 2)
00448     energy += P->TerminalAU;
00449 
00450   return energy;
00451 }
00452 
00453 INLINE  PRIVATE int E_MLstem(int type, int si1, int sj1, paramT *P){
00454   int energy = 0;
00455   if(si1 >= 0 && sj1 >= 0){
00456     energy += P->mismatchM[type][si1][sj1];
00457   }
00458   else if (si1 >= 0){
00459     energy += P->dangle5[type][si1];
00460   }
00461   else if (sj1 >= 0){
00462     energy += P->dangle3[type][sj1];
00463   }
00464 
00465   if(type > 2)
00466     energy += P->TerminalAU;
00467 
00468   energy += P->MLintern[type];
00469 
00470   return energy;
00471 }
00472 
00473 INLINE  PRIVATE double exp_E_Hairpin(int u, int type, short si1, short sj1, const char *string, pf_paramT *P){
00474   double q, kT;
00475   kT = P->kT;   /* kT in cal/mol  */
00476 
00477   if(u <= 30)
00478     q = P->exphairpin[u];
00479   else
00480     q = P->exphairpin[30] * exp( -(P->lxc*log( u/30.))*10./kT);
00481 
00482   if(u < 3) return q; /* should only be the case when folding alignments */
00483 
00484   if ((tetra_loop)&&(u==4)) {
00485     char tl[7]={0,0,0,0,0,0,0}, *ts;
00486     strncpy(tl, string, 6);
00487     if ((ts=strstr(P->Tetraloops, tl))){
00488       if(type != 7)
00489         return (P->exptetra[(ts-P->Tetraloops)/7]);
00490       else
00491         q *= P->exptetra[(ts-P->Tetraloops)/7];
00492     }
00493   }
00494   if ((tetra_loop)&&(u==6)) {
00495     char tl[9]={0,0,0,0,0,0,0,0,0}, *ts;
00496     strncpy(tl, string, 6);
00497     if ((ts=strstr(P->Hexaloops, tl)))
00498       return  (P->exphex[(ts-P->Hexaloops)/9]);
00499   }
00500   if (u==3) {
00501     char tl[6]={0,0,0,0,0,0}, *ts;
00502     strncpy(tl, string, 5);
00503     if ((ts=strstr(P->Triloops, tl)))
00504       return (P->exptri[(ts-P->Triloops)/6]);
00505     if (type>2)
00506       q *= P->expTermAU;
00507   }
00508   else /* no mismatches for tri-loops */
00509     q *= P->expmismatchH[type][si1][sj1];
00510 
00511   return q;
00512 }
00513 
00514 INLINE  PRIVATE double exp_E_IntLoop(int u1, int u2, int type, int type2, short si1, short sj1, short sp1, short sq1, pf_paramT *P){
00515   int ul, us, no_close = 0;
00516   double z;
00517 
00518   if ((no_closingGU) && ((type2==3)||(type2==4)||(type==2)||(type==4)))
00519     no_close = 1;
00520 
00521   if (u1>u2) { ul=u1; us=u2;}
00522   else {ul=u2; us=u1;}
00523 
00524   if (ul==0) /* stack */
00525     z = P->expstack[type][type2];
00526   else if(!no_close){
00527     if (us==0) {                      /* bulge */
00528       z = P->expbulge[ul];
00529       if (ul==1) z *= P->expstack[type][type2];
00530       else {
00531         if (type>2) z *= P->expTermAU;
00532         if (type2>2) z *= P->expTermAU;
00533       }
00534       return z;
00535     }
00536     else if (us==1) {
00537       if (ul==1){                    /* 1x1 loop */
00538         return P->expint11[type][type2][si1][sj1];
00539       }
00540       if (ul==2) {                  /* 2x1 loop */
00541         if (u1==1)
00542           return P->expint21[type][type2][si1][sq1][sj1];
00543         else
00544           return P->expint21[type2][type][sq1][si1][sp1];
00545       }
00546       else {  /* 1xn loop */
00547         z = P->expinternal[ul+us] * P->expmismatch1nI[type][si1][sj1] * P->expmismatch1nI[type2][sq1][sp1];
00548         return z * P->expninio[2][ul-us];
00549       }
00550     }
00551     else if (us==2) {
00552       if(ul==2) /* 2x2 loop */
00553         return P->expint22[type][type2][si1][sp1][sq1][sj1];
00554       else if(ul==3){              /* 2x3 loop */
00555         z = P->expinternal[5]*P->expmismatch23I[type][si1][sj1]*P->expmismatch23I[type2][sq1][sp1];
00556         return z * P->expninio[2][1];
00557       }
00558     }
00559     /* generic interior loop (no else here!)*/
00560     z = P->expinternal[ul+us] * P->expmismatchI[type][si1][sj1] * P->expmismatchI[type2][sq1][sp1];
00561     return z * P->expninio[2][ul-us];
00562 
00563   }
00564   return z;
00565 }
00566 
00567 INLINE  PRIVATE double exp_E_Stem(int type, int si1, int sj1, int extLoop, pf_paramT *P){
00568   double energy = 1.0;
00569   double d5 = (si1 >= 0) ? P->expdangle5[type][si1] : 1.;
00570   double d3 = (sj1 >= 0) ? P->expdangle3[type][sj1] : 1.;
00571 
00572   if(type > 2)
00573     energy *= P->expTermAU;
00574 
00575   if(si1 >= 0 && sj1 >= 0)
00576     energy *= (extLoop) ? P->expmismatchExt[type][si1][sj1] : P->expmismatchM[type][si1][sj1];
00577   else
00578     energy *= d5 * d3;
00579 
00580   if(!extLoop) energy *= P->expMLintern[type];
00581   return energy;
00582 }
00583 
00584 INLINE  PRIVATE double exp_E_MLstem(int type, int si1, int sj1, pf_paramT *P){
00585   double energy = 1.0;
00586   if(si1 >= 0 && sj1 >= 0){
00587     energy *= P->expmismatchM[type][si1][sj1];
00588   }
00589   else if(si1 >= 0){
00590     energy *= P->expdangle5[type][si1];
00591   }
00592   else if(sj1 >= 0){
00593     energy *= P->expdangle3[type][sj1];
00594   }
00595 
00596   if(type > 2)
00597     energy *= P->expTermAU;
00598 
00599   energy *= P->expMLintern[type];
00600   return energy;
00601 }
00602 
00603 INLINE  PRIVATE double exp_E_ExtLoop(int type, int si1, int sj1, pf_paramT *P){
00604   double energy = 1.0;
00605   if(si1 >= 0 && sj1 >= 0){
00606     energy *= P->expmismatchExt[type][si1][sj1];
00607   }
00608   else if(si1 >= 0){
00609     energy *= P->expdangle5[type][si1];
00610   }
00611   else if(sj1 >= 0){
00612     energy *= P->expdangle3[type][sj1];
00613   }
00614 
00615   if(type > 2)
00616     energy *= P->expTermAU;
00617 
00618   return energy;
00619 }
00620 
00621 INLINE  PRIVATE 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, paramT *P){
00622   int energy = 0;
00623   if(type > 2)   energy += P->TerminalAU;
00624   if(type_2 > 2) energy += P->TerminalAU;
00625 
00626   if(!dangles) return energy;
00627 
00628   int ci = (i>=cutpoint)||((i+1)<cutpoint);
00629   int cj = ((j-1)>=cutpoint)||(j<cutpoint);
00630   int cp = ((p-1)>=cutpoint)||(p<cutpoint);
00631   int cq = (q>=cutpoint)||((q+1)<cutpoint);
00632 
00633   int d3    = ci  ? P->dangle3[type][si1]   : 0;
00634   int d5    = cj  ? P->dangle5[type][sj1]   : 0;
00635   int d5_2  = cp  ? P->dangle5[type_2][sp1] : 0;
00636   int d3_2  = cq  ? P->dangle3[type_2][sq1] : 0;
00637 
00638   int tmm   = (cj && ci) ? P->mismatchExt[type][sj1][si1]   : d5 + d3;
00639   int tmm_2 = (cp && cq) ? P->mismatchExt[type_2][sp1][sq1] : d5_2 + d3_2;
00640 
00641   if(dangles == 2) return energy + tmm + tmm_2;
00642 
00643   /* now we may have non-double dangles only */
00644   if(i+2 < p){
00645     if(q+2 < j){ energy += tmm + tmm_2;}
00646     else if(q+2 == j){ energy += (cj && cq) ? MIN2(tmm + d5_2, tmm_2 + d3) : tmm + tmm_2;}
00647     else energy += d3 + d5_2;
00648   }
00649   else if(i+2 == p){
00650     if(q+2 < j){ energy += (ci && cp) ? MIN2(tmm + d3_2, tmm_2 + d5) : tmm + tmm_2;}
00651     else if(q+2 == j){
00652       energy += MIN2(tmm, MIN2(tmm_2, MIN2(d5 + d5_2, d3 + d3_2)));
00653     }
00654     else energy += MIN2(d3, d5_2);
00655   }
00656   else{
00657     if(q+2 < j){ energy += d5 + d3_2;}
00658     else if(q+2 == j){ energy += MIN2(d5, d3_2);}
00659   }
00660   return energy;
00661 }
00662 
00663 #endif