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
00055 INLINE PRIVATE int E_MLstem( int type,
00056 int si1,
00057 int sj1,
00058 paramT *P);
00059
00066
00067 INLINE PRIVATE double exp_E_MLstem(int type,
00068 int si1,
00069 int sj1,
00070 pf_paramT *P);
00071
00091
00092 INLINE PRIVATE int E_ExtLoop(int type,
00093 int si1,
00094 int sj1,
00095 paramT *P);
00096
00103
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
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 (P->model_details.special_hp){
00331 if (size == 4) {
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 else if (size == 6) {
00338 char tl[9]={0}, *ts;
00339 strncpy(tl, string, 8);
00340 if ((ts=strstr(P->Hexaloops, tl)))
00341 return (energy = P->Hexaloop_E[(ts - P->Hexaloops)/9]);
00342 }
00343 else if (size == 3) {
00344 char tl[6]={0,0,0,0,0,0}, *ts;
00345 strncpy(tl, string, 5);
00346 if ((ts=strstr(P->Triloops, tl))) {
00347 return (P->Triloop_E[(ts - P->Triloops)/6]);
00348 }
00349 return (energy + (type>2 ? P->TerminalAU : 0));
00350 }
00351 }
00352 energy += P->mismatchH[type][si1][sj1];
00353
00354 return energy;
00355 }
00356
00357 INLINE PRIVATE int E_IntLoop(int n1, int n2, int type, int type_2, int si1, int sj1, int sp1, int sq1, paramT *P){
00358
00359 int nl, ns, energy;
00360
00361 if (n1>n2) { nl=n1; ns=n2;}
00362 else {nl=n2; ns=n1;}
00363
00364 if (nl == 0)
00365 return P->stack[type][type_2];
00366
00367 if (ns==0) {
00368 energy = (nl<=MAXLOOP)?P->bulge[nl]:
00369 (P->bulge[30]+(int)(P->lxc*log(nl/30.)));
00370 if (nl==1) energy += P->stack[type][type_2];
00371 else {
00372 if (type>2) energy += P->TerminalAU;
00373 if (type_2>2) energy += P->TerminalAU;
00374 }
00375 return energy;
00376 }
00377 else {
00378 if (ns==1) {
00379 if (nl==1)
00380 return P->int11[type][type_2][si1][sj1];
00381 if (nl==2) {
00382 if (n1==1)
00383 energy = P->int21[type][type_2][si1][sq1][sj1];
00384 else
00385 energy = P->int21[type_2][type][sq1][si1][sp1];
00386 return energy;
00387 }
00388 else {
00389 energy = (nl+1<=MAXLOOP)?(P->internal_loop[nl+1]) : (P->internal_loop[30]+(int)(P->lxc*log((nl+1)/30.)));
00390 energy += MIN2(MAX_NINIO, (nl-ns)*P->ninio[2]);
00391 energy += P->mismatch1nI[type][si1][sj1] + P->mismatch1nI[type_2][sq1][sp1];
00392 return energy;
00393 }
00394 }
00395 else if (ns==2) {
00396 if(nl==2) {
00397 return P->int22[type][type_2][si1][sp1][sq1][sj1];}
00398 else if (nl==3){
00399 energy = P->internal_loop[5]+P->ninio[2];
00400 energy += P->mismatch23I[type][si1][sj1] + P->mismatch23I[type_2][sq1][sp1];
00401 return energy;
00402 }
00403
00404 }
00405 {
00406 energy = (n1+n2<=MAXLOOP)?(P->internal_loop[n1+n2]) : (P->internal_loop[30]+(int)(P->lxc*log((n1+n2)/30.)));
00407
00408 energy += MIN2(MAX_NINIO, (nl-ns)*P->ninio[2]);
00409
00410 energy += P->mismatchI[type][si1][sj1] + P->mismatchI[type_2][sq1][sp1];
00411 }
00412 }
00413 return energy;
00414 }
00415
00416 INLINE PRIVATE int E_Stem(int type, int si1, int sj1, int extLoop, paramT *P){
00417 int energy = 0;
00418 int d5 = (si1 >= 0) ? P->dangle5[type][si1] : 0;
00419 int d3 = (sj1 >= 0) ? P->dangle3[type][sj1] : 0;
00420
00421 if(type > 2)
00422 energy += P->TerminalAU;
00423
00424 if(si1 >= 0 && sj1 >= 0)
00425 energy += (extLoop) ? P->mismatchExt[type][si1][sj1] : P->mismatchM[type][si1][sj1];
00426 else
00427 energy += d5 + d3;
00428
00429 if(!extLoop) energy += P->MLintern[type];
00430 return energy;
00431 }
00432
00433 INLINE PRIVATE int E_ExtLoop(int type, int si1, int sj1, paramT *P){
00434 int energy = 0;
00435 if(si1 >= 0 && sj1 >= 0){
00436 energy += P->mismatchExt[type][si1][sj1];
00437 }
00438 else if (si1 >= 0){
00439 energy += P->dangle5[type][si1];
00440 }
00441 else if (sj1 >= 0){
00442 energy += P->dangle3[type][sj1];
00443 }
00444
00445 if(type > 2)
00446 energy += P->TerminalAU;
00447
00448 return energy;
00449 }
00450
00451 INLINE PRIVATE int E_MLstem(int type, int si1, int sj1, paramT *P){
00452 int energy = 0;
00453 if(si1 >= 0 && sj1 >= 0){
00454 energy += P->mismatchM[type][si1][sj1];
00455 }
00456 else if (si1 >= 0){
00457 energy += P->dangle5[type][si1];
00458 }
00459 else if (sj1 >= 0){
00460 energy += P->dangle3[type][sj1];
00461 }
00462
00463 if(type > 2)
00464 energy += P->TerminalAU;
00465
00466 energy += P->MLintern[type];
00467
00468 return energy;
00469 }
00470
00471 INLINE PRIVATE double exp_E_Hairpin(int u, int type, short si1, short sj1, const char *string, pf_paramT *P){
00472 double q, kT;
00473 kT = P->kT;
00474
00475 if(u <= 30)
00476 q = P->exphairpin[u];
00477 else
00478 q = P->exphairpin[30] * exp( -(P->lxc*log( u/30.))*10./kT);
00479
00480 if(u < 3) return q;
00481
00482 if ((P->model_details.special_hp)&&(u==4)) {
00483 char tl[7]={0,0,0,0,0,0,0}, *ts;
00484 strncpy(tl, string, 6);
00485 if ((ts=strstr(P->Tetraloops, tl))){
00486 if(type != 7)
00487 return (P->exptetra[(ts-P->Tetraloops)/7]);
00488 else
00489 q *= P->exptetra[(ts-P->Tetraloops)/7];
00490 }
00491 }
00492 if ((tetra_loop)&&(u==6)) {
00493 char tl[9]={0,0,0,0,0,0,0,0,0}, *ts;
00494 strncpy(tl, string, 6);
00495 if ((ts=strstr(P->Hexaloops, tl)))
00496 return (P->exphex[(ts-P->Hexaloops)/9]);
00497 }
00498 if (u==3) {
00499 char tl[6]={0,0,0,0,0,0}, *ts;
00500 strncpy(tl, string, 5);
00501 if ((ts=strstr(P->Triloops, tl)))
00502 return (P->exptri[(ts-P->Triloops)/6]);
00503 if (type>2)
00504 q *= P->expTermAU;
00505 }
00506 else
00507 q *= P->expmismatchH[type][si1][sj1];
00508
00509 return q;
00510 }
00511
00512 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){
00513 int ul, us, no_close = 0;
00514 double z;
00515
00516 if ((no_closingGU) && ((type2==3)||(type2==4)||(type==3)||(type==4)))
00517 no_close = 1;
00518
00519 if (u1>u2) { ul=u1; us=u2;}
00520 else {ul=u2; us=u1;}
00521
00522 if (ul==0)
00523 z = P->expstack[type][type2];
00524 else if(!no_close){
00525 if (us==0) {
00526 z = P->expbulge[ul];
00527 if (ul==1) z *= P->expstack[type][type2];
00528 else {
00529 if (type>2) z *= P->expTermAU;
00530 if (type2>2) z *= P->expTermAU;
00531 }
00532 return z;
00533 }
00534 else if (us==1) {
00535 if (ul==1){
00536 return P->expint11[type][type2][si1][sj1];
00537 }
00538 if (ul==2) {
00539 if (u1==1)
00540 return P->expint21[type][type2][si1][sq1][sj1];
00541 else
00542 return P->expint21[type2][type][sq1][si1][sp1];
00543 }
00544 else {
00545 z = P->expinternal[ul+us] * P->expmismatch1nI[type][si1][sj1] * P->expmismatch1nI[type2][sq1][sp1];
00546 return z * P->expninio[2][ul-us];
00547 }
00548 }
00549 else if (us==2) {
00550 if(ul==2)
00551 return P->expint22[type][type2][si1][sp1][sq1][sj1];
00552 else if(ul==3){
00553 z = P->expinternal[5]*P->expmismatch23I[type][si1][sj1]*P->expmismatch23I[type2][sq1][sp1];
00554 return z * P->expninio[2][1];
00555 }
00556 }
00557
00558 z = P->expinternal[ul+us] * P->expmismatchI[type][si1][sj1] * P->expmismatchI[type2][sq1][sp1];
00559 return z * P->expninio[2][ul-us];
00560
00561 }
00562 return z;
00563 }
00564
00565 INLINE PRIVATE double exp_E_Stem(int type, int si1, int sj1, int extLoop, pf_paramT *P){
00566 double energy = 1.0;
00567 double d5 = (si1 >= 0) ? P->expdangle5[type][si1] : 1.;
00568 double d3 = (sj1 >= 0) ? P->expdangle3[type][sj1] : 1.;
00569
00570 if(type > 2)
00571 energy *= P->expTermAU;
00572
00573 if(si1 >= 0 && sj1 >= 0)
00574 energy *= (extLoop) ? P->expmismatchExt[type][si1][sj1] : P->expmismatchM[type][si1][sj1];
00575 else
00576 energy *= d5 * d3;
00577
00578 if(!extLoop) energy *= P->expMLintern[type];
00579 return energy;
00580 }
00581
00582 INLINE PRIVATE double exp_E_MLstem(int type, int si1, int sj1, pf_paramT *P){
00583 double energy = 1.0;
00584 if(si1 >= 0 && sj1 >= 0){
00585 energy *= P->expmismatchM[type][si1][sj1];
00586 }
00587 else if(si1 >= 0){
00588 energy *= P->expdangle5[type][si1];
00589 }
00590 else if(sj1 >= 0){
00591 energy *= P->expdangle3[type][sj1];
00592 }
00593
00594 if(type > 2)
00595 energy *= P->expTermAU;
00596
00597 energy *= P->expMLintern[type];
00598 return energy;
00599 }
00600
00601 INLINE PRIVATE double exp_E_ExtLoop(int type, int si1, int sj1, pf_paramT *P){
00602 double energy = 1.0;
00603 if(si1 >= 0 && sj1 >= 0){
00604 energy *= P->expmismatchExt[type][si1][sj1];
00605 }
00606 else if(si1 >= 0){
00607 energy *= P->expdangle5[type][si1];
00608 }
00609 else if(sj1 >= 0){
00610 energy *= P->expdangle3[type][sj1];
00611 }
00612
00613 if(type > 2)
00614 energy *= P->expTermAU;
00615
00616 return energy;
00617 }
00618
00619 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){
00620 int energy = 0;
00621 if(type > 2) energy += P->TerminalAU;
00622 if(type_2 > 2) energy += P->TerminalAU;
00623
00624 if(!dangles) return energy;
00625
00626 int ci = (i>=cutpoint)||((i+1)<cutpoint);
00627 int cj = ((j-1)>=cutpoint)||(j<cutpoint);
00628 int cp = ((p-1)>=cutpoint)||(p<cutpoint);
00629 int cq = (q>=cutpoint)||((q+1)<cutpoint);
00630
00631 int d3 = ci ? P->dangle3[type][si1] : 0;
00632 int d5 = cj ? P->dangle5[type][sj1] : 0;
00633 int d5_2 = cp ? P->dangle5[type_2][sp1] : 0;
00634 int d3_2 = cq ? P->dangle3[type_2][sq1] : 0;
00635
00636 int tmm = (cj && ci) ? P->mismatchExt[type][sj1][si1] : d5 + d3;
00637 int tmm_2 = (cp && cq) ? P->mismatchExt[type_2][sp1][sq1] : d5_2 + d3_2;
00638
00639 if(dangles == 2) return energy + tmm + tmm_2;
00640
00641
00642 if(i+2 < p){
00643 if(q+2 < j){ energy += tmm + tmm_2;}
00644 else if(q+2 == j){ energy += (cj && cq) ? MIN2(tmm + d5_2, tmm_2 + d3) : tmm + tmm_2;}
00645 else energy += d3 + d5_2;
00646 }
00647 else if(i+2 == p){
00648 if(q+2 < j){ energy += (ci && cp) ? MIN2(tmm + d3_2, tmm_2 + d5) : tmm + tmm_2;}
00649 else if(q+2 == j){
00650 energy += MIN2(tmm, MIN2(tmm_2, MIN2(d5 + d5_2, d3 + d3_2)));
00651 }
00652 else energy += MIN2(d3, d5_2);
00653 }
00654 else{
00655 if(q+2 < j){ energy += d5 + d3_2;}
00656 else if(q+2 == j){ energy += MIN2(d5, d3_2);}
00657 }
00658 return energy;
00659 }
00660
00661 #endif