/* compute potentially pseudoknotted structures of an RNA sequence Ivo Hofacker Vienna RNA package */ /* library containing the function used in PKplex it generates pseudoknotted structures by letting the sequence form a duplex structure with itself */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "ViennaRNA/energy_par.h" #include "ViennaRNA/fold_vars.h" #include "ViennaRNA/utils.h" #include "ViennaRNA/params.h" #include "ViennaRNA/loop_energies.h" #include "ViennaRNA/pair_mat.h" #include "ViennaRNA/fold.h" #include "ViennaRNA/PKplex.h" #undef MAXLOOP #define MAXLOOP 10 PRIVATE void update_dfold_params(void); PRIVATE void duplexfold_XS(const char *s1, int **access_s1, const int threshold, const int max_interaction_length); PRIVATE char *backtrack_XS(int kk, int ll, const int ii, const int jj, const int max_interaction_length); PRIVATE void make_ptypes(const char *structure); PRIVATE vrna_param_t *P = NULL; PRIVATE int ***c3 = NULL; /* energy array used in duplexfold */ PRIVATE short *S1 = NULL, *SS1 = NULL; PRIVATE int n1; PRIVATE char *ptype = NULL; /* precomputed array of pair types */ PRIVATE int *indx = NULL; /* index for moving in the triangle matrices ptype[] */ PUBLIC dupVar *PlexHits = NULL; PUBLIC int PlexHitsArrayLength = 100; PUBLIC int NumberOfHits = 0; PUBLIC int verbose = 0; /*-----------------------------------------------------------------------duplexfold_XS---------------------------------------------------------------------------*/ PRIVATE void duplexfold_XS(const char *s1, int **access_s1, const int threshold, const int max_interaction_length){ int i, j, k, l, p, q, Emin=INF, l_min=0, k_min=0, j_min=0; int type, type2, type3, E, tempK; char *struc; int length = (int) strlen(s1); struc=NULL; c3 = (int ***) vrna_alloc(sizeof(int **) * (length)); for (i=0; i 11 ){ Emin=INF; j_min=0; l_min=0; k_min=0; /* init all matrix elements to INF */ for (j=0; j < length; j++){ for(k=0;kDuplexInit; c3[j-11][max_interaction_length-1][0] += E_Hairpin(j-i-1, type, SS1[i+1], SS1[j-1], string, P); /* c3[j-11][max_interaction_length-1][0] += E_ExtLoop(type, SS1[i+1], SS1[j-1], P); */ /* c3[j-11][max_interaction_length-1][0] += E_ExtLoop(rtype[type], SS1[j-1], SS1[i+1], P); */ } } int i_pos_begin=MAX2(9, i-max_interaction_length); /* why 9 ??? */ /* fill matrix */ for(k=i-1; k>i_pos_begin; k--) { tempK=max_interaction_length-i+k-1; for(l = i + 5; l < n1 - 9; l++) { /* again, why 9 less then the sequence length ? */ type2 = ptype[indx[l] + k]; if(!type2) continue; for(p = k + 1; (p <= i) && (p <= k + MAXLOOP + 1); p++){ for(q = l - 1; (q>=i+4) && (q >= l - MAXLOOP - 1); q--){ if (p - k + l - q - 2 > MAXLOOP) break; type3 = ptype[indx[q] + p]; if(!type3) continue; E = E_IntLoop(p - k - 1, l - q - 1, type2, rtype[type3], SS1[k + 1], SS1[l - 1], SS1[p - 1], SS1[q + 1], P); for(j = MAX2(i + 4, l - max_interaction_length + 1); j <= q; j++){ type = ptype[indx[j]+i]; if (type){ c3[j-11][tempK][l-j] = MIN2(c3[j-11][tempK][l-j], c3[j-11][max_interaction_length-i+p-1][q-j]+E); } }/* next j */ }/* next q */ }/* next p */ }/* next l */ }/* next k */ /* read out matrix minimum */ for(j=i+4; ji_pos_begin; k--) { for (l=j+1; li_pos_begin+1)? SS1[k-1]:-1),((l=j) { E = c3[j-11][max_interaction_length-i+k-1][l-j]; traced=0; st1[k-i0] = '('; st2[l-j] = ')'; type=ptype[indx[l]+k]; if (!type) vrna_message_error("backtrack failed in fold duplex bli"); for (p=k+1; p<=i; p++) { for (q=l-1; q>=j; q--) { int LE; if (p-k+l-q-2>MAXLOOP) break; type2=ptype[indx[q]+p]; if (!type2) continue; LE = E_IntLoop(p-k-1, l-q-1, type, rtype[type2], SS1[k+1], SS1[l-1], SS1[p-1], SS1[q+1], P); if (E == c3[j-11][max_interaction_length-i+p-1][q-j]+LE) { traced=1; k=p; l=q; break; } } if (traced) break; } if (!traced) { E-=E_ExtLoop(type2, ((kj-1)? SS1[l-1]:-1), P); break; if (E != P->DuplexInit) { vrna_message_error("backtrack failed in fold duplex bal"); } else break; } } struc = (char *) vrna_alloc(k-i0+1+j0-l+1+2); for (p=0; p<=i-i0; p++){ if (!st1[p]) st1[p] = '.'; } for (p=0; p<=j0-j; p++) { if (!st2[p]) { st2[p] = '.'; } } strcpy(struc, st1); strcat(struc, "&"); strcat(struc, st2); free(st1); free(st2); return struc; } PUBLIC dupVar **PKLduplexfold_XS( const char *s1, int **access_s1, const int threshold, const int max_interaction_length, const int delta){ if ((!P) || (fabs(P->temperature - temperature)>1e-6)) update_dfold_params(); n1 = (int) strlen(s1); S1 = encode_sequence(s1, 0); SS1 = encode_sequence(s1, 1); indx = vrna_idx_col_wise(n1); ptype = (char *) vrna_alloc(sizeof(char)*((n1*(n1+1))/2+2)); make_ptypes(s1); P->DuplexInit=0; duplexfold_XS(s1,access_s1,threshold, max_interaction_length); free(S1); free(SS1); free(indx); free(ptype); return NULL; } /*---------------------------------UTILS------------------------------------------*/ PRIVATE void update_dfold_params(void){ vrna_md_t md; if(P) free(P); set_model_details(&md); P = vrna_params(&md); make_pair_matrix(); } /*---------------------------------------------------------------------------*/ PRIVATE void make_ptypes(const char *structure) { int n,i,j,k,l; n=S1[0]; for (k=1; kn) continue; type = pair[S1[i]][S1[j]]; while ((i>=1)&&(j<=n)) { if ((i>1)&&(j