/*****************************************************************************/ /* */ /* UNIT: NTL1_Predefined_Codes (Level 1 library routine) */ /* */ /* Author: Nikola Stojanovic */ /* */ /* Revision: 31 JUL 94 Version 1.0 */ /* */ /* Function: */ /* */ /* Procedure loads predefined character ambigutity codes and their */ /* inverses into arrays of strings it allocates */ /* */ /*****************************************************************************/ #include #include #include #include "ntl1.h" void NTL1_PC_Expand (char **codes, char current, char *replacement); /*****************************************************************************/ /* */ /* Code section */ /* */ /*****************************************************************************/ /*****************************************************************************/ /* */ /* Procedure: NTL1_Predefined_Codes */ /* */ /* Main (interface) procedure for this utility */ void NTL1_Predefined_Codes (char ***codes, char ***inverses) { int index; char *scan; *codes = (char **) NTL0_ckalloc (26 * sizeof (char *)); *inverses = (char **) NTL0_ckalloc (26 * sizeof (char *)); for (index = 0; index < 26; index++) { (*codes) [index] = (char *) NTL0_ckalloc (2 * sizeof (char)); (*inverses) [index] = (char *) NTL0_ckalloc (2 * sizeof (char)); scan = (*codes) [index]; *scan = (char) index + 'A'; scan++; *scan = '\0'; scan = (*inverses) [index]; *scan = (char) index + 'A'; scan++; *scan = '\0'; } /* Now preload the fixed known codes */ NTL1_PC_Expand (*codes, 'W', "ATW"); NTL1_PC_Expand (*codes, 'Y', "CTY"); NTL1_PC_Expand (*codes, 'S', "CGS"); NTL1_PC_Expand (*codes, 'R', "AGR"); NTL1_PC_Expand (*codes, 'M', "ACM"); NTL1_PC_Expand (*codes, 'K', "GKT"); NTL1_PC_Expand (*codes, 'B', "BCGKSTY"); NTL1_PC_Expand (*codes, 'D', "ADGKRTW"); NTL1_PC_Expand (*codes, 'H', "ACHMTWY"); NTL1_PC_Expand (*codes, 'V', "ACGMRSV"); NTL1_PC_Expand (*codes, 'N', "ABCDGHKMNRSTVWXY"); NTL1_PC_Expand (*codes, 'X', "ABCDGHKMNRSTVWXY"); /* Fill the values of the inverses into the table */ /* ((*inverses) [(int) 'A' - (int) 'A']) [0] = 'T'; */ (*inverses) [(int) 'A' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'T' - (int) 'A']); /* ((*inverses) [(int) 'C' - (int) 'A']) [0] = 'G'; */ (*inverses) [(int) 'C' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'G' - (int) 'A']); /* ((*inverses) [(int) 'G' - (int) 'A']) [0] = 'C'; */ (*inverses) [(int) 'G' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'C' - (int) 'A']); /* ((*inverses) [(int) 'T' - (int) 'A']) [0] = 'A'; */ (*inverses) [(int) 'T' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'A' - (int) 'A']); /* ((*inverses) [(int) 'B' - (int) 'A']) [0] = 'V'; */ (*inverses) [(int) 'B' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'V' - (int) 'A']); /* ((*inverses) [(int) 'D' - (int) 'A']) [0] = 'H'; */ (*inverses) [(int) 'D' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'H' - (int) 'A']); /* ((*inverses) [(int) 'H' - (int) 'A']) [0] = 'D'; */ (*inverses) [(int) 'H' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'D' - (int) 'A']); /* ((*inverses) [(int) 'K' - (int) 'A']) [0] = 'M'; */ (*inverses) [(int) 'K' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'M' - (int) 'A']); /* ((*inverses) [(int) 'M' - (int) 'A']) [0] = 'K'; */ (*inverses) [(int) 'M' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'K' - (int) 'A']); /* ((*inverses) [(int) 'N' - (int) 'A']) [0] = 'N'; */ (*inverses) [(int) 'N' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'N' - (int) 'A']); /* ((*inverses) [(int) 'R' - (int) 'A']) [0] = 'Y'; */ (*inverses) [(int) 'R' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'Y' - (int) 'A']); /* ((*inverses) [(int) 'S' - (int) 'A']) [0] = 'S'; */ (*inverses) [(int) 'S' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'S' - (int) 'A']); /* ((*inverses) [(int) 'V' - (int) 'A']) [0] = 'B'; */ (*inverses) [(int) 'V' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'B' - (int) 'A']); /* ((*inverses) [(int) 'W' - (int) 'A']) [0] = 'W'; */ (*inverses) [(int) 'W' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'W' - (int) 'A']); /* ((*inverses) [(int) 'X' - (int) 'A']) [0] = 'X'; */ (*inverses) [(int) 'X' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'X' - (int) 'A']); /* ((*inverses) [(int) 'Y' - (int) 'A']) [0] = 'R'; */ (*inverses) [(int) 'Y' - (int) 'A'] = NTL0_strsave ((*codes) [(int) 'R' - (int) 'A']); } /*****************************************************************************/ /* */ /* Procedure: NTL1_PC_Expand */ /* */ /* Procedure replaces the current replacement codes for the given character */ /* with the specified string, where each of the characters in the string */ /* is interpreted as a code itself, and is appropriatelly expanded with */ /* respect to the current settings of codes */ void NTL1_PC_Expand (char **codes, char current, char *replacement) { int estimate, position, checker; char *scan, *buffer, *nchars; bool duplicate; /* Estimate the size of the replacement buffer first, as summ of all */ /* expanded characters in the replacement string */ estimate = 0; scan = replacement; while (*scan != '\0') { estimate += strlen (codes [(int) *scan - (int) 'A']); scan++; } buffer = (char *) NTL0_ckalloc ((estimate + 1) * sizeof (char)); /* Now expand the received replacement string with all the character codes */ position = 0; scan = replacement; while (*scan != '\0') { nchars = codes [(int) *scan - (int) 'A']; while (*nchars != '\0') { checker = 0; duplicate = FALSE; while ((!duplicate) && (checker < position)) if (buffer [checker] == *nchars) duplicate = TRUE; else checker++; if (checker == position) buffer [position++] = *nchars; nchars++; } scan++; } buffer [position] = '\0'; /* if (!strcmp (replacement, "CTY")) fprintf (stderr, "%s\n", buffer); */ /* Since the estimate may be much bigger than the actual string, copy buff. */ free (codes [(int) current - (int) 'A']); codes [(int) current - (int) 'A'] = NTL0_strsave (buffer); free (buffer); }