Block *cluster(clus, block)
int clus;
Block *block;
{
   int iclus, npair, threshold, s1, s2, l1, l2, px, i, i1, i2, first;
   int nclus[MAXROWS], icluster[MAXROWS], minclus, oldclus, width, nseq;
   struct pair *pairs;
   Block *newblock;

   width = block->sequences[0].length;
   nseq = block->num_sequences;
   if (nseq > MAXROWS)
   {
     nseq = MAXROWS;
     fprintf(stderr, "ERROR: Block %s is too deep (%d), truncated to %d nseq\n",
		block->number, block->num_sequences, nseq);
   }
   npair = nseq*(nseq-1)/2;
   pairs = (struct pair *) malloc(npair * sizeof(struct pair));
   threshold = (int) (clus*(width))/100;

   /*    Compute scores for all possible pairs of sequences            */
   for (s1=0; s1<nseq-1; s1++)   		/* col = 0, n-2     */
   {
      l1 = 0;
      for (s2=s1+1; s2<nseq; s2++)	/* row = col+1, n-1 */
      {
	 l2 = 0;
	 px = INDEX(nseq, s1, s2);
	 pairs[px].score = 0;
	 pairs[px].cluster = -1;
	 for (i=0; i<=width; i++)
	 {
	    i1 = l1+i;  i2 = l2+i;
	    if (i1 >= 0 && i1 < width &&
		i2 >= 0 && i2 < width &&
		block->residues[s1][i1] == block->residues[s2][i2])
		   pairs[px].score += 1;
	 }
      }  /* end of s2 */
   }  /* end of s1 */

/*  Print scores */
/*   printf("\nThreshold=%d", threshold);
   for (s2=1; s2<nseq; s2++)
   {
      printf ("\n");
      for (s1=0; s1<s2; s1++)
      {
	 px = INDEX(nseq, s1, s2);
	 printf(" %.3d", pairs[px].score);
      }
    }
*/

   /*-------Cluster if score exceeds threshold by scanning cols (s1) */
   for (s1=0; s1<nseq; s1++)
   {
      icluster[s1] = -1;			/* clear out old values */
      nclus[s1] = 0;
   }
   iclus = 0;        				/* cluster number */
   for (s1=0; s1<nseq-1; s1++)   		/* col = 0, n-2     */
      for (s2=s1+1; s2<nseq; s2++)	/* row = col+1, n-1 */
      {
	 px = INDEX(nseq, s1, s2);
	 if (pairs[px].score >= threshold)	/*  cluster this pair */
	 {
	    if (icluster[s1] < 0)          /* s1 not yet clustered */
	    {
	       if (icluster[s2] < 0)       /* new cluster */
	       {
		  icluster[s1] = iclus++;
		  icluster[s2] = icluster[s1];
	       }
	       else  				/* use s2's cluster  */
		  icluster[s1] =  icluster[s2];
	    }
	    /*  use s1's cluster if it has one and s2 doesn't */
	    else if (icluster[s1] >= 0 && icluster[s2] < 0)
	       icluster[s2] = icluster[s1];
	    /* merge the two clusters into the lower number */
	    else if (icluster[s1] >= 0 && icluster[s2] >= 0)
	    {
	       minclus = icluster[s1]; oldclus = icluster[s2];
	       if (icluster[s2] < icluster[s1])
	       {
		  minclus = icluster[s2]; oldclus = icluster[s1];
	       }
	       for (i1=0; i1<nseq; i1++)
		 if (icluster[i1] == oldclus)
		     icluster[i1] = minclus;
	    }
	 }  /* end of if pairs */
      }  /* end of s2 */

   /*---  Set ncluster, get rid of negative cluster numbers --*/
   for (s1=0; s1<nseq; s1++)
   {
      if (icluster[s1] < 0) 
	  icluster[s1] = iclus++;
   }
   for (s1=0; s1<nseq; s1++)
	  nclus[icluster[s1]] += 1;

   /*----------  Now compute the weight for each sequence ------------*/
   for (s1 = 0; s1 < nseq; s1++)
   {
      block->sequences[s1].weight = (double) 1.0 / nclus[icluster[s1]];
   }
   /*----------- Now reorder the block clusters ----------------------*/
   newblock = new_block(width, nseq);	/* allocates 1 Cluster */
   strcpy(newblock->id, block->id);
   strcpy(newblock->ac, block->ac);
   strcpy(newblock->number, block->number);
   strcpy(newblock->de, block->de);
   strcpy(newblock->bl, block->bl);
   newblock->num_clusters = 0;
   newblock->max_clusters = iclus;
   newblock->clusters = (Cluster *) realloc(newblock->clusters, iclus*sizeof(Cluster));
   s2 = 0; i2 = 0;
   for (i=0; i< iclus; i++)
   {
      if (nclus[i] > 0)  /* merged clumps have no members */
      {
         newblock->num_clusters += 1;
         newblock->clusters[i2].num_sequences = nclus[i];
         first = YES;
         for (s1=0; s1 < nseq; s1++)
         {
            if (icluster[s1] == i)
            {
               newblock->sequences[s2] = block->sequences[s1];
               if (first)	/* first sequence for this clump */
               {
                  newblock->clusters[i2].sequences = &(newblock->sequences[s2]);
                  first = NO;
               }
               s2++;
            }
         }
         i2++;
      }
   }
/*
   for (i=0; i<iclus; i++)
   {
     printf("clump %d has %d seqs: ", i, nclus[i]);
     for (s1=0; s1 < nseq; s1++)
        if (icluster[s1] == i) printf(" %d", s1);
     printf("\n");
   }
*/
   free(pairs);
   return(newblock);

}  /* end of cluster */
