/* COPYRIGHT 2001 Fred Hutchinson Cancer Research Center
    rank_matrix.c  Construct aa rank matrix from an aa matrix
	rank_matrix matrix
--------------------------------------------------------------------
12/30/00 J. Henikoff from Pauline Ng's code
====================================================================*/

#define RANK_C_
#define EXTERN
#define MAXNAME 80	/* Maximum file name length */

#include <blocksprogs.h>

struct rank_cell {
        int aa;
        double value;
};
void construct_rank_matrix();
void copy_values_to_ranklist ();
void sort_ranks();
void assign_ranks();
double frequency[MATRIX_AA_WIDTH];    /* for frequency.c */

/*=======================================================================*/

int main(argc, argv)
     int argc;
     char *argv[];
{
  FILE *fmat;
  char matname[MAXNAME];
  struct float_qij *mat;
  int aa1, aa2, rank_matrix[AAS][AAS];
  struct rank_cell aalist[AAS];

/* ------------1st arg = aa score matrix -------------------------------*/
   if (argc > 1)
      strcpy(matname, argv[1]);
   else
   {
      printf("\nEnter name of scoring matrix: ");
      gets(matname);
   }
   if ( (fmat=fopen(matname, "r")) == NULL)
   {
      printf("\nCannot open file %s\n", matname);
      exit(-1);
   }
   mat = load_qij(fmat);
   fclose(fmat);


/*-------This uses $BLIMPD_DIR/docs/default.sij--------------------
   construct_rank_matrix(rank_matrix);
*/

   for (aa1 = 0; aa1 < AAS; aa1++) 
   {
       copy_values_to_ranklist (aalist, aa1, mat);
       sort_ranks (aalist);
       assign_ranks (rank_matrix, aalist, aa1);
   }
  
/*----------------------------------------------------------------------*/
  /*  rank_matrix[aa1][aa2] has ranks for aa1 sorted in the row */
  printf("# Rank matrix constructed from scoring matrix %s\n", matname);
  printf("# Each aa row contains the rank of the score for the all aas\n");
  printf("  ");
  for (aa1=1; aa1< AAS; aa1++) printf(" %c ", aa_btoa[aa1]);
  printf("\n");
  for (aa1=1; aa1< AAS; aa1++)
  {
     printf("%c ", aa_btoa[aa1]);
     for (aa2=1; aa2< AAS; aa2++)
     {
        printf("%2d ", rank_matrix[aa1][aa2]);
     }
     printf("\n");
  }

  free(mat);
  fclose(fmat);
  exit(0);

}  /* end of main */
/*======================================================================*/
void construct_rank_matrix (rank_matrix)
int rank_matrix[AAS][AAS];
{
        struct rank_cell aalist[AAS];
        int original_aa;
	struct float_qij* rank_Qij;
	FILE* sijfp;
        char *blimps_dir, sijname[SMALL_BUFF_LENGTH];

   blimps_dir = getenv("BLIMPS_DIR");
   if (blimps_dir != NULL)
   {
      sprintf(sijname, "%s/docs/default.sij", blimps_dir);
/*>>>>> Need to check that sijname actually exists
        for WWW servers would be better to check in current
        directory first  <<<<<<*/
   }
   else
   {
      sprintf(sijname, "default.sij");
   }

	if ( (sijfp = fopen (sijname, "r")) == NULL) 
        {
            sprintf (ErrorBuffer, "construct_rank_matrix(): Cannot open %s\n",
		sijname);
            ErrorReport(FATAL_ERR_LVL);
	}
        else
	{      rank_Qij = load_qij(sijfp); fclose(sijfp);   }

        for (original_aa = 0; original_aa < AAS; original_aa++) {
                copy_values_to_ranklist (aalist, original_aa, rank_Qij);
                sort_ranks (aalist);
                assign_ranks (rank_matrix, aalist, original_aa);
        }
	free (rank_Qij);
} /* end of construct_rank_matrix */

/*======================================================================*/
void copy_values_to_ranklist (aalist, original_aa, rankQij) 
struct rank_cell aalist[AAS];
int original_aa;
struct float_qij *rankQij;
{

        int aa;

        for (aa = 0; aa < AAS; aa++) {
                aalist[aa].aa = aa;
                aalist[aa].value = rankQij->value[original_aa][aa];
        }
} /* end of copy_values_to_ranklist */

/*======================================================================*/
void sort_ranks (aalist)
struct rank_cell aalist[AAS];
{
        int i, j;
        struct rank_cell tmp;

        /* don't include aalist[0] in the sort, it's for gaps JGH */
        for (i = 2; i < AAS; i++) {
                tmp.aa = aalist[i].aa;
                tmp.value = aalist[i].value;
                for (j = i; j > 1 && aalist[j-1].value < tmp.value; j--) {
                        aalist[j].value = aalist[j-1].value;
                        aalist[j].aa = aalist[j-1].aa;
                }
                aalist[j].value = tmp.value;
                aalist[j].aa = tmp.aa;
        }
} /* end of sort_ranks */

/*======================================================================*/
void assign_ranks (rank_matrix, aalist, original_aa)
int rank_matrix[AAS][AAS];
struct rank_cell aalist[AAS];
int original_aa;
{
        int rank, aa;

        for (rank = 0; rank < AAS; rank++) {
                aa = aalist[rank].aa;
                rank_matrix[original_aa][aa] = rank; 
        }
} /* end of assign_ranks */

