WSTester updated to work plus hopefully all the other changes that need to go into...
[jabaws.git] / binaries / src / ViennaRNA / H / gquad.h
diff --git a/binaries/src/ViennaRNA/H/gquad.h b/binaries/src/ViennaRNA/H/gquad.h
new file mode 100644 (file)
index 0000000..9b8dbdb
--- /dev/null
@@ -0,0 +1,604 @@
+#ifndef __VIENNA_RNA_PACKAGE_GQUAD_H__
+#define __VIENNA_RNA_PACKAGE_GQUAD_H__
+
+#include "data_structures.h"
+
+#ifndef INLINE
+#ifdef __GNUC__
+# define INLINE inline
+#else
+# define INLINE
+#endif
+#endif
+
+/**
+ *  \file gquad.h
+ *  \brief Various functions related to G-quadruplex computations
+ */
+
+
+int         E_gquad(int L,
+                    int l[3],
+                    paramT *P);
+
+FLT_OR_DBL exp_E_gquad( int L,
+                        int l[3],
+                        pf_paramT *pf);
+
+int         E_gquad_ali(int i,
+                        int L,
+                        int l[3],
+                        const short **S,
+                        int n_seq,
+                        paramT *P);
+
+
+void        E_gquad_ali_en( int i,
+                            int L,
+                            int l[3],
+                            const short **S,
+                            int n_seq,
+                            int en[2],
+                            paramT *P);
+
+/**
+ *  \brief Get a triangular matrix prefilled with minimum free energy
+ *  contributions of G-quadruplexes.
+ *
+ *  At each position ij in the matrix, the minimum free energy of any
+ *  G-quadruplex delimited by i and j is stored. If no G-quadruplex formation
+ *  is possible, the matrix element is set to INF.
+ *  Access the elements in the matrix via matrix[indx[j]+i]. To get
+ *  the integer array indx see get_jindx().
+ *
+ *  \see get_jindx(), encode_sequence()
+ *
+ *  \param S  The encoded sequence
+ *  \param P  A pointer to the data structure containing the precomputed energy contributions
+ *  \return   A pointer to the G-quadruplex contribution matrix
+*/
+int         *get_gquad_matrix(short *S, paramT *P);
+
+int         *get_gquad_ali_matrix(short *S_cons,
+                                  short **S,
+                                  int n_seq,
+                                  paramT *P);
+
+FLT_OR_DBL  *get_gquad_pf_matrix( short *S,
+                                  FLT_OR_DBL *scale,
+                                  pf_paramT *pf);
+
+int         **get_gquad_L_matrix( short *S,
+                                  int start,
+                                  int maxdist,
+                                  int **g,
+                                  paramT *P);
+
+void        get_gquad_pattern_mfe(short *S,
+                                  int i,
+                                  int j,
+                                  paramT *P,
+                                  int *L,
+                                  int l[3]);
+
+void        get_gquad_pattern_pf( short *S,
+                                  int i,
+                                  int j,
+                                  pf_paramT *pf,
+                                  int *L,
+                                  int l[3]);
+
+plist       *get_plist_gquad_from_pr( short *S,
+                                      int gi,
+                                      int gj,
+                                      FLT_OR_DBL *G,
+                                      FLT_OR_DBL *probs,
+                                      FLT_OR_DBL *scale,
+                                      pf_paramT *pf);
+plist       *get_plist_gquad_from_pr_max(short *S,
+                                      int gi,
+                                      int gj,
+                                      FLT_OR_DBL *G,
+                                      FLT_OR_DBL *probs,
+                                      FLT_OR_DBL *scale,
+                                      int *L,
+                                      int l[3],
+                                      pf_paramT *pf);
+
+plist       *get_plist_gquad_from_db( const char *structure,
+                                      float pr);
+
+/**
+ *  given a dot-bracket structure (possibly) containing gquads encoded
+ *  by '+' signs, find first gquad, return end position or 0 if none found
+ *  Upon return L and l[] contain the number of stacked layers, as well as
+ *  the lengths of the linker regions.  
+ *  To parse a string with many gquads, call parse_gquad repeatedly e.g.
+ *  end1 = parse_gquad(struc, &L, l); ... ;
+ *  end2 = parse_gquad(struc+end1, &L, l); end2+=end1; ... ;
+ *  end3 = parse_gquad(struc+end2, &L, l); end3+=end2; ... ; 
+ */
+int         parse_gquad(const char *struc, int *L, int l[3]);
+
+
+
+/**
+ *  backtrack an interior loop like enclosed g-quadruplex
+ *  with closing pair (i,j)
+ *
+ *  \param c      The total contribution the loop should resemble
+ *  \param i      position i of enclosing pair
+ *  \param j      position j of enclosing pair
+ *  \param type   base pair type of enclosing pair (must be reverse type)
+ *  \param S      integer encoded sequence
+ *  \param ggg    triangular matrix containing g-quadruplex contributions
+ *  \param index  the index for accessing the triangular matrix
+ *  \param p      here the 5' position of the gquad is stored
+ *  \param q      here the 3' position of the gquad is stored
+ *  \param P      the datastructure containing the precalculated contibutions
+ *
+ *  \return       1 on success, 0 if no gquad found
+ */
+INLINE  PRIVATE int backtrack_GQuad_IntLoop(int c,
+                                            int i,
+                                            int j,
+                                            int type,
+                                            short *S,
+                                            int *ggg,
+                                            int *index,
+                                            int *p,
+                                            int *q,
+                                            paramT *P){
+
+  int energy, dangles, k, l, maxl, minl, c0, l1;
+  short si, sj;
+
+  dangles = P->model_details.dangles;
+  si      = S[i + 1];
+  sj      = S[j - 1];
+  energy  = 0;
+
+  if(dangles == 2)
+    energy += P->mismatchI[type][si][sj];
+
+  if(type > 2)
+    energy += P->TerminalAU;
+
+  k = i + 1;
+  if(S[k] == 3){
+    if(k < j - VRNA_GQUAD_MIN_BOX_SIZE){
+      minl  = j - i + k - MAXLOOP - 2;
+      c0    = k + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+      minl  = MAX2(c0, minl);
+      c0    = j - 3;
+      maxl  = k + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+      maxl  = MIN2(c0, maxl);
+      for(l = minl; l < maxl; l++){
+        if(S[l] != 3) continue;
+        if(c == energy + ggg[index[l] + k] + P->internal_loop[j - l - 1]){
+          *p = k; *q = l;
+          return 1;
+        }
+      }
+    }
+  }
+
+  for(k = i + 2;
+      k < j - VRNA_GQUAD_MIN_BOX_SIZE;
+      k++){
+    l1    = k - i - 1;
+    if(l1>MAXLOOP) break;
+    if(S[k] != 3) continue;
+    minl  = j - i + k - MAXLOOP - 2;
+    c0    = k + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+    minl  = MAX2(c0, minl);
+    c0    = j - 1;
+    maxl  = k + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+    maxl  = MIN2(c0, maxl);
+    for(l = minl; l < maxl; l++){
+      if(S[l] != 3) continue;
+      if(c == energy + ggg[index[l] + k] + P->internal_loop[l1 + j - l - 1]){
+        *p = k; *q = l;
+        return 1;
+      }
+    }
+  }
+
+  l = j - 1;
+  if(S[l] == 3)
+    for(k = i + 4;
+        k < j - VRNA_GQUAD_MIN_BOX_SIZE;
+        k++){
+      l1    = k - i - 1;
+      if(l1>MAXLOOP) break;
+      if(S[k] != 3) continue;
+      if(c == energy + ggg[index[l] + k] + P->internal_loop[l1]){
+        *p = k; *q = l;
+        return 1;
+      }
+    }
+
+  return 0;
+}
+
+/**
+ *  backtrack an interior loop like enclosed g-quadruplex
+ *  with closing pair (i,j) with underlying Lfold matrix
+ *
+ *  \param c      The total contribution the loop should resemble
+ *  \param i      position i of enclosing pair
+ *  \param j      position j of enclosing pair
+ *  \param type   base pair type of enclosing pair (must be reverse type)
+ *  \param S      integer encoded sequence
+ *  \param ggg    triangular matrix containing g-quadruplex contributions
+ *  \param p      here the 5' position of the gquad is stored
+ *  \param q      here the 3' position of the gquad is stored
+ *  \param P      the datastructure containing the precalculated contibutions
+ *
+ *  \return       1 on success, 0 if no gquad found
+ */
+INLINE  PRIVATE int backtrack_GQuad_IntLoop_L(int c,
+                                              int i,
+                                              int j,
+                                              int type,
+                                              short *S,
+                                              int **ggg,
+                                              int maxdist,
+                                              int *p,
+                                              int *q,
+                                              paramT *P){
+
+  int energy, dangles, k, l, maxl, minl, c0, l1;
+  short si, sj;
+
+  dangles = P->model_details.dangles;
+  si      = S[i + 1];
+  sj      = S[j - 1];
+  energy  = 0;
+
+  if(dangles == 2)
+    energy += P->mismatchI[type][si][sj];
+
+  if(type > 2)
+    energy += P->TerminalAU;
+
+  k = i + 1;
+  if(S[k] == 3){
+    if(k < j - VRNA_GQUAD_MIN_BOX_SIZE){
+      minl  = j - i + k - MAXLOOP - 2;
+      c0    = k + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+      minl  = MAX2(c0, minl);
+      c0    = j - 3;
+      maxl  = k + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+      maxl  = MIN2(c0, maxl);
+      for(l = minl; l < maxl; l++){
+        if(S[l] != 3) continue;
+        if(c == energy + ggg[k][l - k] + P->internal_loop[j - l - 1]){
+          *p = k; *q = l;
+          return 1;
+        }
+      }
+    }
+  }
+
+  for(k = i + 2;
+      k < j - VRNA_GQUAD_MIN_BOX_SIZE;
+      k++){
+    l1    = k - i - 1;
+    if(l1>MAXLOOP) break;
+    if(S[k] != 3) continue;
+    minl  = j - i + k - MAXLOOP - 2;
+    c0    = k + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+    minl  = MAX2(c0, minl);
+    c0    = j - 1;
+    maxl  = k + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+    maxl  = MIN2(c0, maxl);
+    for(l = minl; l < maxl; l++){
+      if(S[l] != 3) continue;
+      if(c == energy + ggg[k][l - k] + P->internal_loop[l1 + j - l - 1]){
+        *p = k; *q = l;
+        return 1;
+      }
+    }
+  }
+
+  l = j - 1;
+  if(S[l] == 3)
+    for(k = i + 4;
+        k < j - VRNA_GQUAD_MIN_BOX_SIZE;
+        k++){
+      l1    = k - i - 1;
+      if(l1>MAXLOOP) break;
+      if(S[k] != 3) continue;
+      if(c == energy + ggg[k][l - k] + P->internal_loop[l1]){
+        *p = k; *q = l;
+        return 1;
+      }
+    }
+
+  return 0;
+}
+
+INLINE PRIVATE
+int
+E_GQuad_IntLoop(int i,
+                int j,
+                int type,
+                short *S,
+                int *ggg,
+                int *index,
+                paramT *P){
+
+  int energy, ge, en1, en2, dangles, p, q, l1, minq, maxq;
+  int c0, c1, c2, c3, up, d53, d5, d3;
+  short si, sj;
+
+  dangles = P->model_details.dangles;
+  si      = S[i + 1];
+  sj      = S[j - 1];
+  energy  = 0;
+
+  if(dangles == 2)
+    energy += P->mismatchI[type][si][sj];
+
+  if(type > 2)
+    energy += P->TerminalAU;
+
+  ge = INF;
+
+  p = i + 1;
+  if(S[p] == 3){
+    if(p < j - VRNA_GQUAD_MIN_BOX_SIZE){
+      minq  = j - i + p - MAXLOOP - 2;
+      c0    = p + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+      minq  = MAX2(c0, minq);
+      c0    = j - 3;
+      maxq  = p + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+      maxq  = MIN2(c0, maxq);
+      for(q = minq; q < maxq; q++){
+        if(S[q] != 3) continue;
+        c0  = energy + ggg[index[q] + p] + P->internal_loop[j - q - 1];
+        ge  = MIN2(ge, c0);
+      }
+    }
+  }
+
+  for(p = i + 2;
+      p < j - VRNA_GQUAD_MIN_BOX_SIZE;
+      p++){
+    l1    = p - i - 1;
+    if(l1>MAXLOOP) break;
+    if(S[p] != 3) continue;
+    minq  = j - i + p - MAXLOOP - 2;
+    c0    = p + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+    minq  = MAX2(c0, minq);
+    c0    = j - 1;
+    maxq  = p + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+    maxq  = MIN2(c0, maxq);
+    for(q = minq; q < maxq; q++){
+      if(S[q] != 3) continue;
+      c0  = energy + ggg[index[q] + p] + P->internal_loop[l1 + j - q - 1];
+      ge   = MIN2(ge, c0);
+    }
+  }
+
+  q = j - 1;
+  if(S[q] == 3)
+    for(p = i + 4;
+        p < j - VRNA_GQUAD_MIN_BOX_SIZE;
+        p++){
+      l1    = p - i - 1;
+      if(l1>MAXLOOP) break;
+      if(S[p] != 3) continue;
+      c0  = energy + ggg[index[q] + p] + P->internal_loop[l1];
+      ge  = MIN2(ge, c0);
+    }
+
+#if 0
+  /* here comes the additional stuff for the odd dangle models */
+  if(dangles % 1){
+    en1 = energy + P->dangle5[type][si];
+    en2 = energy + P->dangle5[type][sj];
+    en3 = energy + P->mismatchI[type][si][sj];
+
+    /* first case with 5' dangle (i.e. j-1) onto enclosing pair */
+    p = i + 1;
+    if(S[p] == 3){
+      if(p < j - VRNA_GQUAD_MIN_BOX_SIZE){
+        minq  = j - i + p - MAXLOOP - 2;
+        c0    = p + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+        minq  = MAX2(c0, minq);
+        c0    = j - 4;
+        maxq  = p + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+        maxq  = MIN2(c0, maxq);
+        for(q = minq; q < maxq; q++){
+          if(S[q] != 3) continue;
+          c0  = en1 + ggg[index[q] + p] + P->internal_loop[j - q - 1];
+          ge  = MIN2(ge, c0);
+        }
+      }
+    }
+
+    for(p = i + 2; p < j - VRNA_GQUAD_MIN_BOX_SIZE; p++){
+      l1    = p - i - 1;
+      if(l1>MAXLOOP) break;
+      if(S[p] != 3) continue;
+      minq  = j - i + p - MAXLOOP - 2;
+      c0    = p + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+      minq  = MAX2(c0, minq);
+      c0    = j - 2;
+      maxq  = p + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+      maxq  = MIN2(c0, maxq);
+      for(q = minq; q < maxq; q++){
+        if(S[q] != 3) continue;
+        c0  = en1 + ggg[index[q] + p] + P->internal_loop[l1 + j - q - 1];
+        ge   = MIN2(ge, c0);
+      }
+    }
+
+    q = j - 2;
+    if(S[q] == 3)
+      for(p = i + 4; p < j - VRNA_GQUAD_MIN_BOX_SIZE; p++){
+        l1    = p - i - 1;
+        if(l1>MAXLOOP) break;
+        if(S[p] != 3) continue;
+        c0  = en1 + ggg[index[q] + p] + P->internal_loop[l1 + 1];
+        ge  = MIN2(ge, c0);
+      }
+
+    /* second case with 3' dangle (i.e. i+1) onto enclosing pair */
+
+  }
+#endif
+  return ge;
+}
+
+INLINE PRIVATE
+int
+E_GQuad_IntLoop_L(int i,
+                  int j,
+                  int type,
+                  short *S,
+                  int **ggg,
+                  int maxdist,
+                  paramT *P){
+
+  int energy, ge, en1, en2, dangles, p, q, l1, minq, maxq;
+  int c0, c1, c2, c3, up, d53, d5, d3;
+  short si, sj;
+
+  dangles = P->model_details.dangles;
+  si      = S[i + 1];
+  sj      = S[j - 1];
+  energy  = 0;
+
+  if(dangles == 2)
+    energy += P->mismatchI[type][si][sj];
+
+  if(type > 2)
+    energy += P->TerminalAU;
+
+  ge = INF;
+
+  p = i + 1;
+  if(S[p] == 3){
+    if(p < j - VRNA_GQUAD_MIN_BOX_SIZE){
+      minq  = j - i + p - MAXLOOP - 2;
+      c0    = p + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+      minq  = MAX2(c0, minq);
+      c0    = j - 3;
+      maxq  = p + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+      maxq  = MIN2(c0, maxq);
+      for(q = minq; q < maxq; q++){
+        if(S[q] != 3) continue;
+        c0  = energy + ggg[p][q-p] + P->internal_loop[j - q - 1];
+        ge  = MIN2(ge, c0);
+      }
+    }
+  }
+
+  for(p = i + 2;
+      p < j - VRNA_GQUAD_MIN_BOX_SIZE;
+      p++){
+    l1    = p - i - 1;
+    if(l1>MAXLOOP) break;
+    if(S[p] != 3) continue;
+    minq  = j - i + p - MAXLOOP - 2;
+    c0    = p + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+    minq  = MAX2(c0, minq);
+    c0    = j - 1;
+    maxq  = p + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+    maxq  = MIN2(c0, maxq);
+    for(q = minq; q < maxq; q++){
+      if(S[q] != 3) continue;
+      c0  = energy + ggg[p][q - p] + P->internal_loop[l1 + j - q - 1];
+      ge   = MIN2(ge, c0);
+    }
+  }
+
+  q = j - 1;
+  if(S[q] == 3)
+    for(p = i + 4;
+        p < j - VRNA_GQUAD_MIN_BOX_SIZE;
+        p++){
+      l1    = p - i - 1;
+      if(l1>MAXLOOP) break;
+      if(S[p] != 3) continue;
+      c0  = energy + ggg[p][q - p] + P->internal_loop[l1];
+      ge  = MIN2(ge, c0);
+    }
+
+  return ge;
+}
+
+INLINE PRIVATE
+FLT_OR_DBL
+exp_E_GQuad_IntLoop(int i,
+                    int j,
+                    int type,
+                    short *S,
+                    FLT_OR_DBL *G,
+                    int *index,
+                    pf_paramT *pf){
+
+  int k, l, minl, maxl, u, r;
+  FLT_OR_DBL q, qe, *expintern;
+  short si, sj;
+
+  q         = 0;
+  si        = S[i + 1];
+  sj        = S[j - 1];
+  qe        = pf->expmismatchI[type][si][sj];
+  expintern = pf->expinternal;
+
+  if(type > 2)
+    qe *= pf->expTermAU;
+
+  k = i + 1;
+  if(S[k] == 3){
+    if(k < j - VRNA_GQUAD_MIN_BOX_SIZE){
+      minl  = j - i + k - MAXLOOP - 2;
+      u     = k + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+      minl  = MAX2(u, minl);
+      u     = j - 3;
+      maxl  = k + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+      maxl  = MIN2(u, maxl);
+      for(l = minl; l < maxl; l++){
+        if(S[l] != 3) continue;
+        q += qe * G[index[k]-l] * expintern[j - l - 1];
+      }
+    }
+  }
+
+
+  for(k = i + 2;
+      k <= j - VRNA_GQUAD_MIN_BOX_SIZE;
+      k++){
+    u = k - i - 1;
+    if(u > MAXLOOP) break;
+    if(S[k] != 3) continue;
+    minl  = j - i + k - MAXLOOP - 2;
+    r     = k + VRNA_GQUAD_MIN_BOX_SIZE - 1;
+    minl  = MAX2(r, minl);
+    maxl  = k + VRNA_GQUAD_MAX_BOX_SIZE + 1;
+    r     = j - 1;
+    maxl  = MIN2(r, maxl);
+    for(l = minl; l < maxl; l++){
+      if(S[l] != 3) continue;
+      q += qe * G[index[k]-l] * expintern[u + j - l - 1];
+    }
+  }
+
+  l = j - 1;
+  if(S[l] == 3)
+    for(k = i + 4; k < j - VRNA_GQUAD_MIN_BOX_SIZE; k++){
+      u    = k - i - 1;
+      if(u>MAXLOOP) break;
+      if(S[k] != 3) continue;
+      q += qe * G[index[k]-l] * expintern[u];
+    }
+
+  return q;
+}
+
+#endif