jpayne@69: #include "tigrinc.hh" jpayne@69: jpayne@69: jpayne@69: FILE * File_Open (const char * Filename, const char * Mode) jpayne@69: jpayne@69: /* Open Filename in Mode and return a pointer to its control jpayne@69: * block. If fail, print a message and exit. */ jpayne@69: jpayne@69: { jpayne@69: FILE * fp; jpayne@69: jpayne@69: fp = fopen (Filename, Mode); jpayne@69: if (fp == NULL) jpayne@69: { jpayne@69: fprintf (stderr, "ERROR: Could not open file %s \n", Filename); jpayne@69: exit (EXIT_FAILURE); jpayne@69: } jpayne@69: jpayne@69: return fp; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: jpayne@69: void * Safe_calloc (size_t N, size_t Len) jpayne@69: jpayne@69: /* Allocate and return a pointer to an array of N elements of jpayne@69: * Len bytes each. All set to 0. Exit if fail. */ jpayne@69: jpayne@69: { jpayne@69: void * P; jpayne@69: jpayne@69: P = calloc (N, Len); jpayne@69: if (P == NULL) jpayne@69: { jpayne@69: fprintf (stderr, jpayne@69: "ERROR: calloc failed, there is not enough memory\n"); jpayne@69: exit (EXIT_FAILURE); jpayne@69: } jpayne@69: jpayne@69: return P; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: jpayne@69: void * Safe_malloc (size_t Len) jpayne@69: jpayne@69: /* Allocate and return a pointer to Len bytes of memory. jpayne@69: * Exit if fail. */ jpayne@69: jpayne@69: { jpayne@69: void * P; jpayne@69: jpayne@69: P = malloc (Len); jpayne@69: if (P == NULL) jpayne@69: { jpayne@69: fprintf (stderr, jpayne@69: "ERROR: malloc failed, there is not enough memory\n"); jpayne@69: exit (EXIT_FAILURE); jpayne@69: } jpayne@69: jpayne@69: return P; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: jpayne@69: void * Safe_realloc (void * Q, size_t Len) jpayne@69: jpayne@69: /* Reallocate memory for Q to Len bytes and return a jpayne@69: * pointer to the new memory. Exit if fail. */ jpayne@69: jpayne@69: { jpayne@69: void * P; jpayne@69: jpayne@69: P = realloc (Q, Len); jpayne@69: if (P == NULL) jpayne@69: { jpayne@69: fprintf (stderr, jpayne@69: "ERROR: realloc failed, there is not enough memory\n"); jpayne@69: exit (EXIT_FAILURE); jpayne@69: } jpayne@69: jpayne@69: return P; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: jpayne@69: char Complement (char Ch) jpayne@69: jpayne@69: /* Returns the DNA complement of Ch . */ jpayne@69: jpayne@69: { jpayne@69: switch (tolower (Ch)) jpayne@69: { jpayne@69: case 'a' : jpayne@69: return 't'; jpayne@69: case 'c' : jpayne@69: return 'g'; jpayne@69: case 'g' : jpayne@69: return 'c'; jpayne@69: case 't' : jpayne@69: return 'a'; jpayne@69: case 'r' : // a or g jpayne@69: return 'y'; jpayne@69: case 'y' : // c or t jpayne@69: return 'r'; jpayne@69: case 's' : // c or g jpayne@69: return 's'; jpayne@69: case 'w' : // a or t jpayne@69: return 'w'; jpayne@69: case 'm' : // a or c jpayne@69: return 'k'; jpayne@69: case 'k' : // g or t jpayne@69: return 'm'; jpayne@69: case 'b' : // c, g or t jpayne@69: return 'v'; jpayne@69: case 'd' : // a, g or t jpayne@69: return 'h'; jpayne@69: case 'h' : // a, c or t jpayne@69: return 'd'; jpayne@69: case 'v' : // a, c or g jpayne@69: return 'b'; jpayne@69: default : // anything jpayne@69: return tolower (Ch); jpayne@69: } jpayne@69: } jpayne@69: jpayne@69: jpayne@69: bool CompareIUPAC (char x, char y) jpayne@69: { jpayne@69: x = tolower(x); jpayne@69: y = tolower(y); jpayne@69: jpayne@69: if ( x == 'n' || x == 'x' || y == 'n' || y == 'x' ) jpayne@69: return true; jpayne@69: jpayne@69: switch ( x ) jpayne@69: { jpayne@69: case 'a' : jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'a': jpayne@69: case 'r': jpayne@69: case 'w': jpayne@69: case 'm': jpayne@69: case 'd': jpayne@69: case 'h': jpayne@69: case 'v': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'c' : jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'c': jpayne@69: case 'y': jpayne@69: case 's': jpayne@69: case 'm': jpayne@69: case 'b': jpayne@69: case 'h': jpayne@69: case 'v': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'g' : jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'g': jpayne@69: case 'r': jpayne@69: case 's': jpayne@69: case 'k': jpayne@69: case 'b': jpayne@69: case 'd': jpayne@69: case 'v': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 't' : jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 't': jpayne@69: case 'y': jpayne@69: case 'w': jpayne@69: case 'k': jpayne@69: case 'b': jpayne@69: case 'd': jpayne@69: case 'h': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'r' : // a or g jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'r': jpayne@69: case 'a': jpayne@69: case 'g': jpayne@69: case 'd': jpayne@69: case 'v': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'y' : // c or t jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'y': jpayne@69: case 'c': jpayne@69: case 't': jpayne@69: case 'b': jpayne@69: case 'h': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 's' : // c or g jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 's': jpayne@69: case 'c': jpayne@69: case 'g': jpayne@69: case 'b': jpayne@69: case 'v': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'w' : // a or t jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'w': jpayne@69: case 'a': jpayne@69: case 't': jpayne@69: case 'd': jpayne@69: case 'h': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'm' : // a or c jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'm': jpayne@69: case 'a': jpayne@69: case 'c': jpayne@69: case 'h': jpayne@69: case 'v': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'k' : // g or t jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'k': jpayne@69: case 'g': jpayne@69: case 't': jpayne@69: case 'b': jpayne@69: case 'd': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'b' : // c, g or t jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'b': jpayne@69: case 'c': jpayne@69: case 'g': jpayne@69: case 't': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'd' : // a, g or t jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'd': jpayne@69: case 'a': jpayne@69: case 'g': jpayne@69: case 't': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'h' : // a, c or t jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'h': jpayne@69: case 'a': jpayne@69: case 'c': jpayne@69: case 't': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: jpayne@69: case 'v' : // a, c or g jpayne@69: switch ( y ) jpayne@69: { jpayne@69: case 'v': jpayne@69: case 'a': jpayne@69: case 'c': jpayne@69: case 'g': jpayne@69: return true; jpayne@69: } jpayne@69: return false; jpayne@69: } jpayne@69: return false; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: int Read_String (FILE * fp, char * & T, long int & Size, char Name [], jpayne@69: int Partial) jpayne@69: jpayne@69: /* Read next string from fp (assuming FASTA format) into T [1 ..] jpayne@69: * which has Size characters. Allocate extra memory if needed jpayne@69: * and adjust Size accordingly. Return TRUE if successful, FALSE jpayne@69: * otherwise (e.g., EOF). Partial indicates if first line has jpayne@69: * numbers indicating a subrange of characters to read. jpayne@69: */ jpayne@69: jpayne@69: { jpayne@69: char * P, Line [MAX_LINE]; jpayne@69: long int Len, Lo, Hi; jpayne@69: int Ch, Ct; jpayne@69: jpayne@69: while ((Ch = fgetc (fp)) != EOF && Ch != '>') jpayne@69: ; jpayne@69: jpayne@69: if (Ch == EOF) jpayne@69: return FALSE; jpayne@69: jpayne@69: fgets (Line, MAX_LINE, fp); jpayne@69: Len = strlen (Line); jpayne@69: assert (Len > 0 && Line [Len - 1] == '\n'); jpayne@69: P = strtok (Line, " \t\n"); jpayne@69: if (P != NULL) jpayne@69: strcpy (Name, P); jpayne@69: else jpayne@69: Name [0] = '\0'; jpayne@69: Lo = 0; Hi = LONG_MAX; jpayne@69: if (Partial) jpayne@69: { jpayne@69: P = strtok (NULL, " \t\n"); jpayne@69: if (P != NULL) jpayne@69: { jpayne@69: Lo = strtol (P, NULL, 10); jpayne@69: P = strtok (NULL, " \t\n"); jpayne@69: if (P != NULL) jpayne@69: Hi = strtol (P, NULL, 10); jpayne@69: } jpayne@69: assert (Lo <= Hi); jpayne@69: } jpayne@69: jpayne@69: Ct = 0; jpayne@69: T [0] = '\0'; jpayne@69: Len = 1; jpayne@69: while ((Ch = fgetc (fp)) != EOF && Ch != '>') jpayne@69: { jpayne@69: if (isspace (Ch)) jpayne@69: continue; jpayne@69: jpayne@69: Ct ++; jpayne@69: if (Ct < Lo || Ct > Hi) jpayne@69: continue; jpayne@69: jpayne@69: if (Len >= Size) jpayne@69: { jpayne@69: Size += INCR_SIZE; jpayne@69: T = (char *) Safe_realloc (T, Size); jpayne@69: } jpayne@69: Ch = tolower (Ch); jpayne@69: jpayne@69: if (! isalpha (Ch) && Ch != '*') jpayne@69: { jpayne@69: fprintf (stderr, "Unexpected character `%c\' in string %s\n", jpayne@69: Ch, Name); jpayne@69: Ch = 'x'; jpayne@69: } jpayne@69: jpayne@69: T [Len ++] = Ch; jpayne@69: } jpayne@69: jpayne@69: T [Len] = '\0'; jpayne@69: if (Ch == '>') jpayne@69: ungetc (Ch, fp); jpayne@69: jpayne@69: return TRUE; jpayne@69: } jpayne@69: jpayne@69: jpayne@69: jpayne@69: void Reverse_Complement jpayne@69: (char S [], long int Lo, long int Hi) jpayne@69: jpayne@69: // Convert substring S [Lo .. Hi] to its Watson-Crick reverse jpayne@69: // complement jpayne@69: jpayne@69: { jpayne@69: char Ch; jpayne@69: jpayne@69: while (Lo <= Hi) jpayne@69: { jpayne@69: Ch = S [Hi]; jpayne@69: S [Hi] = Complement (S [Lo]); jpayne@69: S [Lo] = Complement (Ch); jpayne@69: Lo ++; jpayne@69: Hi --; jpayne@69: } jpayne@69: jpayne@69: return; jpayne@69: } jpayne@69: