multiAlign.c
上传用户:szpanda
上传日期:2016-03-09
资源大小:9k
文件大小:11k
源码类别:

DNA

开发平台:

C/C++

  1. /* File: multiAlign.c                      */ 
  2. /* Author:Qichan Ma, Student No.:250494898 */
  3. #include "globals.h"
  4. #include "pairwiseAlign.h"
  5. #include "multiAlign.h"
  6. /* creat a new set whose only member is x */
  7. void Make_set(int x) {
  8.  
  9.     parent[x] = x;
  10.     rank[x] = 0;  
  11. }
  12. /* subroutine of Union */
  13. void Link(int x, int y) {
  14.     if(rank[x] > rank[y])
  15.         parent[y] = x;
  16.     else if(rank[x] < rank[y])
  17.         parent[x] = y;
  18.     else if(x != y) {
  19.         parent[y] = x;
  20.         rank[x] += 1;
  21.     }
  22. }
  23. /* unite the dynamic sets that contain x and y into one set */    
  24. void Union(int x, int y) {
  25.     Link(Find_set(x), Find_set(y));  
  26. }  
  27.  
  28. /* returns a pointer to the representative of the set containing x */    
  29. int Find_set(int x) {
  30.     if(x != parent[x])
  31.         parent[x] = Find_set(parent[x]);
  32.     
  33.     return parent[x];     
  34. }
  35. /* adjust down the element in the heap */
  36. void AdjustDown (int r, int n) 
  37. {  /* r is the index of the element we need to adjust */ 
  38.    int child; 
  39.    int temp=heap[r]; 
  40.    child=2*r;  /* child is the left child of r */
  41.    while  (child<=n) {
  42.      if (( child < n) && ( e[heap[child]-1].cost < e[heap[child+1]-1].cost))  
  43.          child++;
  44.      if (e[temp-1].cost >= e[heap[child]-1].cost) 
  45.          break;
  46.      heap[child/2]=heap[child];
  47.      child*=2; 
  48.    }
  49.    heap[child/2]=temp;
  50. }
  51. /* bulid the heap */
  52. void BuildMaxHeap(int n)
  53.     int i;
  54.     for(i=(int)n/2;i>0;i--) 
  55.         AdjustDown(i,n);
  56. }
  57. /* delete the minimal element from the heap */
  58. int DeleteMax() { 
  59.    int max=heap[1];
  60.    heap[1]=heap[hsize--];/* put the last element on the first position */
  61.    AdjustDown(1,hsize);  /* adjust to minheap */
  62.    return max;
  63. }
  64. /* do the multiple sequence alignment using Kruskal's maximum spanning tree algorithm */
  65. void MST_Kruskal() {
  66.       
  67.     int i, j;
  68.     /* the number of the edges of the complete graph */
  69.     int numOfEdge = numOfSeq*(numOfSeq-1)/2;
  70.     e = (Edge *)malloc(numOfEdge*sizeof(Edge));   /* the edges array  */
  71.     parent = (int *)malloc(numOfSeq*sizeof(int)); /* the parent array */
  72.     rank = (int *)malloc(numOfSeq*sizeof(int));   /* the rank array   */
  73.     heap = (int *)malloc((numOfEdge+1)*sizeof(int)); /* the heap used to sort edges and get the minimal cost edge */
  74.     
  75.     int k=0;
  76.     /* initialize the edges with vertex and cost*/
  77.     for(i=0; i<numOfSeq; i++){
  78.         for(j=i+1; j<numOfSeq; j++) {
  79.             e[k].u = i;
  80.             e[k].v = j;
  81.             e[k].cost = pairwiseScore(seq[i], seq[j]);
  82.             k++;
  83.         }
  84.     } 
  85.                 
  86.     int maxMultiAlignLen = 0; /* the maximal length of the multiple alignments */
  87.     for(i=0; i<numOfSeq; i++)
  88.         maxMultiAlignLen += seqLen[i];
  89.     /* initialize the multiAlign array */ 
  90.     multiAlign = (char **)malloc(numOfSeq*sizeof(char *));
  91. for (i=0; i<numOfSeq; i++)
  92.         multiAlign[i] = (char *)malloc(maxMultiAlignLen*sizeof(char));
  93.     for(i=0; i<numOfSeq; i++){
  94.         strcpy(multiAlign[i], seq[i]);
  95.     } 
  96.     /* initialize the Union-Find sets */    
  97.     for(i=0; i<numOfSeq; i++)
  98.          Make_set(i);
  99.     
  100.     /* initialize the heap */ 
  101.     hsize=numOfEdge;
  102.     for(i=1; i<=hsize; i++)
  103.         heap[i]=i;
  104.     BuildMaxHeap(hsize);
  105.     int a, b, p, q, len1, len2, len3, block;
  106.     while(hsize>0) { 
  107.         i=DeleteMax();
  108.         a=Find_set(e[i-1].u);
  109.         b=Find_set(e[i-1].v);
  110.         /*if a,b are in the different sets, align the 2 sequences and  unite the 2 sets with adjustment */
  111.         if(a !=b ) {
  112.             pairwiseAlign(seq[e[i-1].u], seq[e[i-1].v]);
  113.             if(opt2 == 2) {
  114.                 fprintf(out, "align Sequences(%d, %d) with cost %dn", e[i-1].u+1, e[i-1].v+1, e[i-1].cost);
  115.                 fprintf(out, "the optiaml pairwise alignment of Sequences(%d, %d) with score %d:n", e[i-1].u+1, e[i-1].v+1, e[i-1].cost);
  116.                 len1 = strlen(align1);
  117.                 block = (len1/50)+1; 
  118.                 for (q=0; q<block-1; q++) {
  119.                     fprintf(out, "(Sequence %2d)  %4d  ", e[i-1].u+1, q*50+1); 
  120.                     for(j=q*50; j<(q+1)*50; j++) 
  121.                         fprintf(out, "%c",align1[j]); 
  122.                     fprintf(out, "n");
  123.                     fprintf(out, "(Sequence %2d)  %4d  ", e[i-1].v+1, q*50+1);
  124.                     for(j=q*50; j<(q+1)*50; j++) 
  125.                         fprintf(out, "%c",align2[j]);
  126.                     fprintf(out, "nn");
  127.                 }
  128.                 if((block-1)*50 < len1) {
  129.                     fprintf(out, "(Sequence %2d)  %4d  ", e[i-1].u+1, (block-1)*50+1);
  130.                     for(j=(block-1)*50; j<len1; j++) 
  131.                         fprintf(out, "%c",align1[j]); 
  132.                     fprintf(out, "n");
  133.                     fprintf(out, "(Sequence %2d)  %4d  ", e[i-1].v+1, (block-1)*50+1);
  134.                     for(j=(block-1)*50; j<len1; j++) 
  135.                         fprintf(out, "%c",align2[j]);
  136.                     fprintf(out, "nn");
  137.                 }
  138.             }
  139.             
  140.             /*  unite the 2 sets with adjustment */
  141.             for(j=0; (align1[j]!= '' || multiAlign[e[i-1].u][j]!= '') || (align2[j]!= '' || multiAlign[e[i-1].v][j]!= ''); j++) {
  142.                 len1=strlen(align1); 
  143.                 len2=strlen(multiAlign[e[i-1].u]);
  144.                 len3=strlen(multiAlign[e[i-1].v]); 
  145.                 
  146.                 if(align1[j]=='-' && multiAlign[e[i-1].u][j]!='-') {
  147.                     for(p=0; p<numOfSeq; p++) { 
  148.                         if(Find_set(p) == a) {
  149.                             for(k=len2; k>=j; k--)
  150.                                 multiAlign[p][k+1] = multiAlign[p][k];
  151.                             multiAlign[p][j]='-';
  152.                             
  153.                         }
  154.                     }
  155.                 }   
  156.                 else if(align2[j]=='-' && multiAlign[e[i-1].v][j]!='-') {
  157.                     for(p=0; p<numOfSeq; p++) { 
  158.                         if(Find_set(p) == b) {
  159.                             for(k=len3; k>=j; k--)
  160.                                 multiAlign[p][k+1] = multiAlign[p][k];
  161.                             multiAlign[p][j]='-';
  162.                             
  163.                         }
  164.                     }
  165.                 }  
  166.                 else if(multiAlign[e[i-1].u][j]=='-' && align1[j]!='-') {
  167.                     for(k=len1; k>=j; k--) {
  168.                         align1[k+1] = align1[k];
  169.                         align2[k+1] = align2[k];
  170.                     }
  171.                     align1[j] = align2[j] = '-';
  172.                     for(p=0; p<numOfSeq; p++) { 
  173.                         if(Find_set(p) == b) {
  174.                             for(k=len3; k>=j; k--)
  175.                                 multiAlign[p][k+1] = multiAlign[p][k];
  176.                             multiAlign[p][j]='-';
  177.                             
  178.                         }
  179.                     }    
  180.                 } 
  181.                 else if(multiAlign[e[i-1].v][j]=='-' && align2[j]!='-') {
  182.                     for(k=len1; k>=j; k--) {
  183.                         align1[k+1] = align1[k];
  184.                         align2[k+1] = align2[k];
  185.                     }
  186.                     align1[j] = align2[j] = '-';
  187.                     for(p=0; p<numOfSeq; p++) { 
  188.                         if(Find_set(p) == a) {
  189.                             for(k=len2; k>=j; k--)
  190.                                 multiAlign[p][k+1] = multiAlign[p][k];
  191.                             multiAlign[p][j]='-';
  192.                             
  193.                         }
  194.                     }    
  195.                 } 
  196.             }                      
  197.             Union(a,b); /* unite the 2 sets */
  198.             /* output the current multiple alignment */
  199.             if(opt2 == 2) {
  200.                 fprintf(out, "unite 2 sets and adjust the sequences in the sets, the current multiple alignment is:n");
  201.                 len1 = strlen(multiAlign[0]);
  202.                 block = (len1/50)+1;    
  203.                 for (q=0; q<block-1; q++) { 
  204.                     for(p=0; p<numOfSeq; p++) {
  205.                         if(Find_set(p)==a || Find_set(p)==b) {
  206.                             fprintf(out, "(Sequence %2d)  %4d  ", p+1, q*50+1);
  207.                             for(j=q*50; j<(q+1)*50; j++) 
  208.                                 fprintf(out, "%c",multiAlign[p][j]);
  209.                             fprintf(out, "n");
  210.                         }
  211.                     }
  212.                         fprintf(out, "n");
  213.                 }
  214.                 if((block-1)*50 < len1) {
  215.                     for(p=0; p<numOfSeq; p++) {
  216.                         if(Find_set(p)==a || Find_set(p)==b) {
  217.                             fprintf(out, "(Sequence %2d)  %4d  ", p+1, (block-1)*50+1);
  218.                             for(j=(block-1)*50; j<len1; j++)
  219.                                 fprintf(out, "%c",multiAlign[p][j]);
  220.                             fprintf(out, "n");
  221.                         }
  222.                     }
  223.                     fprintf(out, "n"); 
  224.                 }
  225.                 fprintf(out, "nnn");
  226.             } 
  227.         }
  228.     }
  229.     free(e);
  230.     free(parent);
  231.     free(rank);
  232.     free(heap);  
  233. }
  234. /* compute the pairwise alignment score */
  235. int AlignScore(char *x, char *y){
  236.     int n = strlen(x);
  237.     int sum=0, gap_ext=-2, gap_ini=-8;
  238.     int i;
  239.     if(x[0]!='-' && y[0]!='-')
  240.         sum += score[alphaIndex[x[0]-65]][alphaIndex[y[0]-65]];
  241.     else if((x[0]=='-' && y[0]!='-')||(y[0]=='-' && x[0]!='-')) 
  242.         sum += gap_ini+gap_ext;
  243.     for(i=1; i<n; i++) {
  244.         if (x[i]!='-' && y[i]!='-')
  245.             sum += score[alphaIndex[x[i]-65]][alphaIndex[y[i]-65]]; 
  246.         else if ((x[i]=='-' && y[i]!='-')||(y[i]=='-' && x[i]!='-')) {
  247.             sum += gap_ext;
  248.             if ((x[i]=='-' && x[i-1]!='-')||(y[i]=='-' && y[i-1]!='-')||(x[i-1]=='-' && y[i-1]=='-'))
  249.                 sum += gap_ini;
  250.             }
  251. }
  252.    
  253.     return sum;
  254. }
  255. /* output the multiple alignment & SP score */
  256. void printMultiAlign() {
  257.     int i, j, k ;
  258.     /* compute and output the SP score of the multiple alignment */
  259.     int sum=0; 
  260.     for(i=0; i<numOfSeq; i++){
  261.         for(j=i+1; j<numOfSeq; j++) {
  262.             sum += AlignScore(multiAlign[i], multiAlign[j]);
  263.         }
  264.     } 
  265.     fprintf(out, "The score of the multiple alignment using maximum spanning tree is: %dnn", sum);
  266.     /* output the multiple alignment */
  267.     fprintf(out, "The multiple sequence alignment using maximum spanning tree is:n"); 
  268.     for(i=0; i<numOfSeq; i++){
  269.         fprintf(out, "Sequence %2d:  %sn", i+1, seqName[i]);
  270.     } 
  271.     fprintf(out, "n");
  272.     
  273.     int len = strlen(multiAlign[0]);
  274.     int block = (len/50)+1;    
  275.     for (k=0; k<block-1; k++) { 
  276.         for(i=0; i<numOfSeq; i++){
  277.             fprintf(out, "(Sequence %2d)  %4d  ", i+1, k*50+1);
  278.             for(j=k*50; j<(k+1)*50; j++) 
  279.                 fprintf(out, "%c",multiAlign[i][j]);
  280.             fprintf(out, "n");
  281.         }
  282.         fprintf(out, "n");
  283.     }
  284.     if((block-1)*50 < len) {
  285.         for(i=0; i<numOfSeq; i++){
  286.             fprintf(out, "(Sequence %2d)  %4d  ", i+1, (block-1)*50+1);
  287.             for(j=(block-1)*50; j<len; j++)
  288.                 fprintf(out, "%c",multiAlign[i][j]);
  289.             fprintf(out, "n");
  290.         }
  291.         fprintf(out, "n"); 
  292.     }
  293. }