WSTester updated to work plus hopefully all the other changes that need to go into...
[jabaws.git] / binaries / src / ViennaRNA / Cluster / statgeom.c
diff --git a/binaries/src/ViennaRNA/Cluster/statgeom.c b/binaries/src/ViennaRNA/Cluster/statgeom.c
new file mode 100644 (file)
index 0000000..60d46e5
--- /dev/null
@@ -0,0 +1,515 @@
+/*      Quadruple Statistics on an arbitrary alphabet    
+
+              Vienna RNA Package   ---  Peter F Stadler   1993
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <strings.h>
+#include <string.h>
+#include <ctype.h>
+#include "utils.h"
+#include "PS3D.h"
+#include "distance_matrix.h"
+
+#define PUBLIC    
+#define PRIVATE    static
+
+#define MIN2(A, B)         ((A) < (B) ? (A) : (B))
+#define MIN4(A, B, C, D)   MIN2( (MIN2((A),(B))), (MIN2((C),(D))) )
+#define MAX2(A, B)         ((A) > (B) ? (A) : (B))
+#define MAX4(A, B, C, D)   MAX2( (MAX2((A),(B))), (MAX2((C),(D))) )
+
+PRIVATE int IBox[16];
+
+
+PUBLIC float *statgeom(char **seqs, int n_of_seqs);
+PUBLIC float *statgeom4(char **ss[4], int nn[4]);
+PUBLIC void   printf_stg(float *B);
+
+PRIVATE void SingleBox(char *x1, char *x2, char *x3, char *x4);
+PRIVATE void SortSingleBox(void);
+
+/* ----------------------------------------------------------------------- */
+
+PUBLIC float *statgeom(char **seqs, int n_of_seqs)
+{
+   int i,j,k,l;
+   int i1;
+
+   float *B;
+ float  temp;
+   
+   if(n_of_seqs < 4) {
+      fprintf(stderr,"Less than 4 sequences for statistical geometry.\n");
+      return NULL;
+   }
+
+   B = (float *) space(16*sizeof(float));
+
+   for(i=3; i<n_of_seqs; i++) {
+    for(j=2; j<i; j++) {
+     for(k=1; k<j; k++) {
+      for(l=0; l<k; l++) {
+          SingleBox(seqs[i], seqs[j], seqs[k], seqs[l]);
+          SortSingleBox();
+          B[0] = (float) IBox[0];      /* transfer length */
+          for(i1=1;i1<=15;i1++) B[i1] += ( (float) IBox[i1] );
+      }
+     }
+    }
+   }
+
+   temp = (float) n_of_seqs;
+   temp = temp*(temp-1.)*(temp-2.)*(temp-3.)/24.;
+   for(i1=1;i1<=15;i1++) B[i1] /= (temp*B[0]);
+
+   return B;
+}
+   
+/* ----------------------------------------------------------------------- */
+
+PUBLIC float *statgeom4(char **ss[4], int  nn[4])
+{
+   int i,j,k,l;
+   int i1;
+
+   float *B;
+   float  temp;
+   
+   B = (float *) space(16*sizeof(float));
+
+   for(i=0; i<nn[0]; i++) {
+    for(j=0; j<nn[1]; j++) {
+     for(k=0; k<nn[2]; k++) {
+      for(l=0; l<nn[3]; l++) {
+          SingleBox(ss[0][i], ss[1][j], ss[2][k], ss[3][l]);
+          B[0] = (float) IBox[0];      /* transfer length */
+          for(i1=1;i1<=15;i1++) B[i1] += ( (float) IBox[i1] );
+      }
+     }
+    }
+   }
+
+   for (temp = 1, i=0;i<4;i++) temp *= ((float) nn[i]) ;
+   for(i1=1;i1<=15;i1++) B[i1] /= (temp*B[0]);
+
+   return B;
+}
+/* ------------------------------------------------------------------------- */
+
+PUBLIC void printf_stg(float *B)
+{
+   printf("> Statistical Geometry.\n");
+   printf("> %d (sequence length)\n", (int) B[0]);
+   printf("> AAAA\n");
+   printf("  %7.5f\n", B[1]);
+   printf("> BAAA        ABAA        AABA        AAAB\n");
+   printf("  %7.5f    %7.5f     %7.5f     %7.5f\n", B[2],B[3],B[4],B[5]); 
+   printf("> AABB        ABAB        ABBA\n");
+   printf("  %7.5f    %7.5f     %7.5f\n", B[6],B[7],B[8]);
+   printf("> AABC        ABAC        ABCA        BAAC        BACA        BCAA\n");
+   printf("  %7.5f    %7.5f     %7.5f     %7.5f    %7.5f    %7.5f\n"
+            ,B[9],B[10],B[11],B[12],B[13],B[14]);
+   printf("> ABCD\n");
+   printf("  %7.5f\n",B[15]);
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+PUBLIC void SimplifiedBox(float *B, char *filename)
+{
+   char *tmp, temp[50];
+   float X,Y,Z;
+   float T,P;
+   float t1, t2, t3, t4;
+   float p1, p2, p3, p4;
+   float x1, x2, y1, y2,z1,z2;
+   FILE *fp;
+   float view[3] = {0.3, 1.5, 0.1};
+   float axis[3] = {1.0, 0.0, 0.0};
+
+   t1 = B[9]+B[10]+B[11]+B[15];
+   t2 = B[9]+B[12]+B[13]+B[15];
+   t3 = B[10]+B[12]+B[14]+B[15];
+   t4 = B[11]+B[13]+B[14]+B[15];
+
+   p1 = B[2]; p2 = B[3]; p3 = B[4]; p4 = B[5];
+
+   x1 = B[6] + B[14];
+   x2 = B[6] + B[9];
+   y1 = B[7] + B[13];
+   y2 = B[7] + B[10];
+   z1 = B[8] + B[12];
+   z2 = B[8] + B[11];
+
+   X = (x1+x2)/2.;  Y = (y1+y2)/2.;  Z = (z1+z2)/2;
+   T = (t1+t2+t3+t4)/4.;
+   P = (p1+p2+p3+p4)/4.;
+   
+   printf("> X = %7.5f \n",X);
+   printf("> Y = %7.5f \n",Y);
+   printf("> Z = %7.5f \n",Z);
+   printf("> T = %7.5f \n",T);
+   printf("> P = %7.5f \n",P);
+
+   tmp = get_taxon_label(-1);      /* retrieve the dataset identifier */
+   
+   temp[0]='\0';
+   if(tmp) { strcat(temp,tmp);strcat(temp,"_"); free(tmp); }
+   strcat(temp,filename);
+   
+   fp = fopen(temp,"w");
+   if (fp!=NULL) {
+      ps3d_Preambel(fp, view, axis, "N");
+      PS_DrawSimplifiedBox(X,Y,Z,T,P, fp);
+      fclose(fp);
+   } else fprintf(stderr,"couldn't open %s -- not drawing box\n", temp);
+}
+
+
+      
+/* ------------------------------------------------------------------------- */
+      
+PRIVATE void SingleBox(char *x1, char *x2, char *x3, char *x4)
+{
+   int   len,i1,j1,k1,i,M,m;
+   int   d[4];
+   char  t[4];
+
+   len=strlen(x1);
+   if(strlen(x2)!=len) nrerror("Sequences of unequal length in 'SingleBox'");
+   if(strlen(x3)!=len) nrerror("Sequences of unequal length in 'SingleBox'");
+   if(strlen(x4)!=len) nrerror("Sequences of unequal length in 'SingleBox'");
+
+   IBox[0] = len;
+   for(i=1; i<=15; i++) IBox[i] = 0;
+
+   for(i1=0;i1<len;i1++) {
+      t[0] = x1[i1];
+      t[1] = x2[i1];
+      t[2] = x3[i1];
+      t[3] = x4[i1];
+      for(j1=0;j1<4;j1++) {
+         d[j1]=4;
+         for(k1=0;k1<4;k1++) d[j1] -=(t[j1]!=t[k1]);
+      }
+      M=MAX4(d[0],d[1],d[2],d[3]);
+      switch(M) {
+       case 4 :     /* Four of a kind */
+         IBox[1]++;                            /*  A A A A */
+         break;
+       case 3 :     /* Three of a kind */
+         if(d[0] == 1)      IBox[2]++;         /*  B A A A */
+         else if(d[1] == 1) IBox[3]++;         /*  A B A A */
+         else if(d[2] == 1) IBox[4]++;         /*  A A B A */
+         else               IBox[5]++;         /*  A A A B */
+         break;
+       case 2 : 
+         m=MIN4(d[0],d[1],d[2],d[3]);
+         if(m==2){   /* Two Pairs */
+            if(t[1]==t[0])       IBox[6]++;    /*  A A B B */
+            else if(t[2]==t[0])  IBox[7]++;    /*  A B A B */
+            else                 IBox[8]++;    /*  A B B A */
+         }
+         else {      /* One Pair */  
+            if(d[0]==2){  /* 0 is in the pair */
+               if(t[1]==t[0])      IBox[9]++;  /*  A A B C */
+               else if(t[2]==t[0]) IBox[10]++; /*  A B A C */
+               else                IBox[11]++ ;/*  A B C A */
+            }
+            else if(d[1]==2){  /* 1 is in the pair */
+               if(t[2]==t[1])      IBox[12]++; /*  B A A C */
+               else                IBox[13]++; /*  B A C A */
+            }
+            else                   IBox[14]++; /*  B C A A */
+         }
+         break;
+       case 1 :      /* No Pair */
+         IBox[15]++;                           /*  A B C D */
+         break;
+       default:
+         nrerror("This can't happen.");
+      } 
+   }
+}
+
+/* ----------------------------------------------------------------------- */
+
+PRIVATE void SortSingleBox(void)
+{
+   int i;
+   int M; 
+   int IBB[16];
+   int s[4];
+
+   M = MAX2(MAX2( IBox[6], IBox[7] ), IBox[8] );
+   
+   if( M== IBox[6] ) {                   /* 12|34       */
+      IBB[6] = IBox[6];
+      if( IBox[9] >= IBox[14] ) {        /* 1,2 > 3,4   */
+         IBB[9]  = IBox[9]; 
+         IBB[14] = IBox[14];
+         if( IBox[7] >= IBox[8] ) {      /*    13|24    */
+            IBB[7] = IBox[7];
+            IBB[8] = IBox[8];
+            if( IBox[10] >= IBox[13] ) { /* 1>2>3>4     */
+               IBB[10] = IBox[10];
+               IBB[13] = IBox[13];
+               IBB[11] = IBox[11];
+               IBB[12] = IBox[12];
+               s[0]=0; s[1]=1; s[2]=2; s[3]=3;            /*  1 2 3 4 */
+            }
+            else {                       /* 2>1>4>3     */
+               IBB[10] = IBox[13];
+               IBB[13] = IBox[10];
+               IBB[11] = IBox[12];
+               IBB[12] = IBox[11];
+               s[0]=1; s[1]=0; s[2]=3; s[3]=2;            /*  2 1 4 3 */
+            }
+         }
+         else {                          /*    14|23    */
+            IBB[7] = IBox[8];
+            IBB[8] = IBox[7];
+            if( IBox[11] >= IBox[12]) {   /* 1>2>4>3     */
+               IBB[10] = IBox[11];
+               IBB[13] = IBox[12];
+               IBB[11] = IBox[10];
+               IBB[12] = IBox[13];
+               s[0]=0; s[1]=1; s[2]=3; s[3]=2;            /*  1 2 4 3 */
+            }
+            else {                       /* 2>1>3>4     */
+               IBB[10] = IBox[12]; 
+               IBB[13] = IBox[11];
+               IBB[11] = IBox[13];
+               IBB[12] = IBox[10];
+               s[0]=1; s[1]=0; s[2]=2; s[3]=3;            /*  2 1 3 4 */
+            } 
+         }
+      }
+      else {                             /* 3,4 > 1,2   */
+         IBB[9] = IBox[14];
+         IBB[14]= IBox[9];
+         if( IBox[7] >= IBox[8] ) {      /*    31|42    */
+            IBB[7] = IBox[7];
+            IBB[8] = IBox[8];
+            if(IBox[10] >= IBox[13]) {   /* 3>4>1>2     */
+               IBB[10] = IBox[10];
+               IBB[13] = IBox[13];
+               IBB[11] = IBox[12];
+               IBB[12] = IBox[11];
+               s[0]=2; s[1]=3; s[2]=0; s[3]=1;            /*  3 4 1 2 */
+            }
+            else {                       /*            */
+               IBB[10] = IBox[13];
+               IBB[13] = IBox[10];
+               IBB[11] = IBox[11];
+               IBB[12] = IBox[12];
+               s[0]=3; s[1]=2; s[2]=1; s[3]=0;            /*  4 3 2 1 */
+            }
+         }
+         else {                          /*    32|14    */
+            IBB[7] = IBox[8];
+            IBB[8] = IBox[7];
+            if( IBox[11] >= IBox[12]) {   /* 3>4>2>1     */
+               IBB[10] = IBox[12];
+               IBB[13] = IBox[11];
+               IBB[11] = IBox[10];
+               IBB[12] = IBox[13];
+               s[0]=2; s[1]=3; s[2]=1; s[3]=0;            /*  3 4 2 1 */
+            }
+            else {                       /* 2>1>3>4     */
+               IBB[10] = IBox[10];
+               IBB[13] = IBox[13];
+               IBB[11] = IBox[12];
+               IBB[12] = IBox[11];
+               s[0]=2; s[1]=3; s[2]=0; s[3]=1;            /*  3 4 1 2 */
+            } 
+         }
+      }
+   }
+   else if (M == IBox[7] ) {             /* 13|24       */
+      IBB[6] = IBox[7];
+      if( IBox[10] >= IBox[13] ) {       /* 1,3 > 2,4   */
+         IBB[9]  = IBox[10]; 
+         IBB[14] = IBox[13];         
+         if( IBox[6] >= IBox[8]) {       /*    12|34    */
+            IBB[7] = IBox[6];
+            IBB[8] = IBox[8];
+            if( IBox[9] >= IBox[14] ) {  /*    1,2>3,4  */
+               IBB[10] = IBox[9];
+               IBB[13] = IBox[14];
+               IBB[11] = IBox[11];
+               IBB[12] = IBox[12];
+               s[0]=0; s[1]=2; s[2]=1; s[3]=3;            /* 1 3 2 4 */
+            }
+            else {
+               IBB[10] = IBox[14];
+               IBB[13] = IBox[9];
+               IBB[11] = IBox[12];
+               IBB[12] = IBox[11];
+               s[0]=2; s[1]=0; s[2]=3; s[3]=1;            /* 3 1 4 2 */
+            }    
+         }
+         else {                          /*    14|23   */
+            IBB[7] = IBox[8];
+            IBB[8] = IBox[6];
+            if( IBox[11] >= IBox[12] ){  /*    1,4 > 2,3 */
+               IBB[10] = IBox[11];
+               IBB[13] = IBox[12];
+               IBB[11] = IBox[9];
+               IBB[12] = IBox[14];
+               s[0]=0; s[1]=2; s[2]=3; s[3]=1;            /* 1 3 4 2 */
+            }
+            else {
+               IBB[10] = IBox[12];
+               IBB[13] = IBox[11];
+               IBB[11] = IBox[14];
+               IBB[12] = IBox[9];
+               s[0]=2; s[1]=0; s[2]=1; s[3]=3;            /* 3 1 2 4 */
+            }
+         }
+      }
+      else {                             /* 2,4 > 1,3   */
+         IBB[9]  = IBox[13]; 
+         IBB[14] = IBox[10];         
+         if( IBox[6] >= IBox[8]) {       /*    21|43    */
+            IBB[7] = IBox[6];
+            IBB[8] = IBox[8];
+            if( IBox[9] >= IBox[14] ) {  /*    2,1>4,3  */
+               IBB[10] = IBox[9];
+               IBB[13] = IBox[14];
+               IBB[11] = IBox[12];
+               IBB[12] = IBox[11];
+               s[0]=1; s[1]=3; s[2]=0; s[3]=2;            /* 2 4 1 3 */
+            }
+            else {
+               IBB[10] = IBox[14];
+               IBB[13] = IBox[9];
+               IBB[11] = IBox[11];
+               IBB[12] = IBox[12];
+               s[0]=3; s[1]=1; s[2]=2; s[3]=0;            /* 4 2 3 1 */
+            }    
+         }
+         else {                          /*    14|23   */
+            IBB[7] = IBox[8];
+            IBB[8] = IBox[6];
+            if( IBox[11] >= IBox[12] ){  /*    1,4 > 2,3 */
+               IBB[10] = IBox[11];
+               IBB[13] = IBox[12];
+               IBB[11] = IBox[14];
+               IBB[12] = IBox[9];
+               s[0]=3; s[1]=1; s[2]=0; s[3]=2;            /* 4 2 1 3 */
+            }
+            else {
+               IBB[10] = IBox[12];
+               IBB[13] = IBox[11];
+               IBB[11] = IBox[9];
+               IBB[12] = IBox[14];
+               s[0]=1; s[1]=3; s[2]=2; s[3]=0;            /* 2 4 3 1 */
+            }
+         }
+      }
+   }
+   else {                                /* 14 | 23   */
+      IBB[6] = IBox[8];
+      if( IBox[11] >= IBox[12] ) {       /* 1,4 > 2,3 */
+         IBB[9]  = IBox[11]; 
+         IBB[14] = IBox[12];   
+         if(IBox[6] >= IBox[7]) {        /*    12|34  */
+            IBB[7] = IBox[6];
+            IBB[8] = IBox[7];             
+            if(IBox[9] >= IBox[14]) {   /*    1,2>3,4 */
+               IBB[10] = IBox[9];
+               IBB[13] = IBox[14];
+               IBB[11] = IBox[10];
+               IBB[12] = IBox[13];
+               s[0]=0; s[1]=3; s[2]=1; s[3]=2;          /* 1 4 2 3 */
+            }
+            else {                      /*    4,3>2,1 */
+               IBB[10] = IBox[14];
+               IBB[13] = IBox[9];
+               IBB[11] = IBox[13];
+               IBB[12] = IBox[10];
+               s[0]=3; s[1]=0; s[2]=2; s[3]=1;          /* 4 1 3 2 */
+            }
+         }
+         else {                         /*    13|24  */
+            IBB[7] = IBox[7];
+            IBB[8] = IBox[6];       
+            if( IBox[10] >= IBox[13]) { /*    1,3 > 2,4 */
+               IBB[10] = IBox[10];
+               IBB[13] = IBox[13];
+               IBB[11] = IBox[9];
+               IBB[12] = IBox[14];
+               s[0]=0; s[1]=3; s[2]=2; s[3]=1;          /* 1 4 3 2 */
+            }
+            else {
+               IBB[10] = IBox[13];
+               IBB[13] = IBox[10];
+               IBB[11] = IBox[14];
+               IBB[12] = IBox[9];
+               s[0]=3; s[1]=0; s[2]=1; s[3]=2;          /* 4 1 2 3 */
+            }
+         }
+      }
+      else {                             /* 2,3 > 1,4 */
+         IBB[9]  = IBox[12]; 
+         IBB[14] = IBox[11];   
+         if(IBox[6] >= IBox[7]) {       /*    34|12  */
+            IBB[7] = IBox[6];
+            IBB[8] = IBox[7];
+            if(IBox[9] >= IBox[14]) {   /*    2,1>4,3 */
+               IBB[10] = IBox[9];
+               IBB[13] = IBox[14];
+               IBB[11] = IBox[13];
+               IBB[12] = IBox[10];
+               s[0]=1; s[1]=2; s[2]=0; s[3]=3;          /* 2 3 1 4 */
+            }
+            else {                      /*    4,3>2,1 */
+               IBB[10] = IBox[14];
+               IBB[13] = IBox[9];
+               IBB[11] = IBox[10];
+               IBB[12] = IBox[13];
+               s[0]=2; s[1]=1; s[2]=3; s[3]=0;          /* 3 2 4 1 */
+            }
+         }
+         else {                         /*    31|42  */
+            IBB[7] = IBox[7];
+            IBB[8] = IBox[6];
+            if( IBox[10] >= IBox[13]) { /*    1,3 > 2,4 */
+               IBB[10] = IBox[10];
+               IBB[13] = IBox[13];
+               IBB[11] = IBox[14];
+               IBB[12] = IBox[9];
+               s[0]=2; s[1]=1; s[2]=0; s[3]=4;          /* 3 2 1 4 */
+            }
+            else {
+               IBB[10] = IBox[13];
+               IBB[13] = IBox[10];
+               IBB[11] = IBox[9];
+               IBB[12] = IBox[14];
+               s[0]=1; s[1]=2; s[2]=3; s[3]=0;          /* 2 3 4 1 */
+            }
+         }
+      }      
+   }
+   /* HEUREKA */
+   IBB[0] = IBox[0];
+   IBB[1] = IBox[1];
+   IBB[2] = IBox[2+s[0]];
+   IBB[3] = IBox[2+s[1]];
+   IBB[4] = IBox[2+s[2]];
+   IBB[5] = IBox[2+s[3]];
+   /* 
+   IBB[6...14] see above :-) 
+   */
+   IBB[15] = IBox[15];
+   
+   for(i=0;i<=15;i++) IBox[i] = IBB[i];
+}
+
+/* ----------------------------------------------------------------------- */         
+