jpayne@69
|
1 #include "tigrinc.hh"
|
jpayne@69
|
2
|
jpayne@69
|
3
|
jpayne@69
|
4 FILE * File_Open (const char * Filename, const char * Mode)
|
jpayne@69
|
5
|
jpayne@69
|
6 /* Open Filename in Mode and return a pointer to its control
|
jpayne@69
|
7 * block. If fail, print a message and exit. */
|
jpayne@69
|
8
|
jpayne@69
|
9 {
|
jpayne@69
|
10 FILE * fp;
|
jpayne@69
|
11
|
jpayne@69
|
12 fp = fopen (Filename, Mode);
|
jpayne@69
|
13 if (fp == NULL)
|
jpayne@69
|
14 {
|
jpayne@69
|
15 fprintf (stderr, "ERROR: Could not open file %s \n", Filename);
|
jpayne@69
|
16 exit (EXIT_FAILURE);
|
jpayne@69
|
17 }
|
jpayne@69
|
18
|
jpayne@69
|
19 return fp;
|
jpayne@69
|
20 }
|
jpayne@69
|
21
|
jpayne@69
|
22
|
jpayne@69
|
23
|
jpayne@69
|
24 void * Safe_calloc (size_t N, size_t Len)
|
jpayne@69
|
25
|
jpayne@69
|
26 /* Allocate and return a pointer to an array of N elements of
|
jpayne@69
|
27 * Len bytes each. All set to 0. Exit if fail. */
|
jpayne@69
|
28
|
jpayne@69
|
29 {
|
jpayne@69
|
30 void * P;
|
jpayne@69
|
31
|
jpayne@69
|
32 P = calloc (N, Len);
|
jpayne@69
|
33 if (P == NULL)
|
jpayne@69
|
34 {
|
jpayne@69
|
35 fprintf (stderr,
|
jpayne@69
|
36 "ERROR: calloc failed, there is not enough memory\n");
|
jpayne@69
|
37 exit (EXIT_FAILURE);
|
jpayne@69
|
38 }
|
jpayne@69
|
39
|
jpayne@69
|
40 return P;
|
jpayne@69
|
41 }
|
jpayne@69
|
42
|
jpayne@69
|
43
|
jpayne@69
|
44
|
jpayne@69
|
45 void * Safe_malloc (size_t Len)
|
jpayne@69
|
46
|
jpayne@69
|
47 /* Allocate and return a pointer to Len bytes of memory.
|
jpayne@69
|
48 * Exit if fail. */
|
jpayne@69
|
49
|
jpayne@69
|
50 {
|
jpayne@69
|
51 void * P;
|
jpayne@69
|
52
|
jpayne@69
|
53 P = malloc (Len);
|
jpayne@69
|
54 if (P == NULL)
|
jpayne@69
|
55 {
|
jpayne@69
|
56 fprintf (stderr,
|
jpayne@69
|
57 "ERROR: malloc failed, there is not enough memory\n");
|
jpayne@69
|
58 exit (EXIT_FAILURE);
|
jpayne@69
|
59 }
|
jpayne@69
|
60
|
jpayne@69
|
61 return P;
|
jpayne@69
|
62 }
|
jpayne@69
|
63
|
jpayne@69
|
64
|
jpayne@69
|
65
|
jpayne@69
|
66 void * Safe_realloc (void * Q, size_t Len)
|
jpayne@69
|
67
|
jpayne@69
|
68 /* Reallocate memory for Q to Len bytes and return a
|
jpayne@69
|
69 * pointer to the new memory. Exit if fail. */
|
jpayne@69
|
70
|
jpayne@69
|
71 {
|
jpayne@69
|
72 void * P;
|
jpayne@69
|
73
|
jpayne@69
|
74 P = realloc (Q, Len);
|
jpayne@69
|
75 if (P == NULL)
|
jpayne@69
|
76 {
|
jpayne@69
|
77 fprintf (stderr,
|
jpayne@69
|
78 "ERROR: realloc failed, there is not enough memory\n");
|
jpayne@69
|
79 exit (EXIT_FAILURE);
|
jpayne@69
|
80 }
|
jpayne@69
|
81
|
jpayne@69
|
82 return P;
|
jpayne@69
|
83 }
|
jpayne@69
|
84
|
jpayne@69
|
85
|
jpayne@69
|
86
|
jpayne@69
|
87 char Complement (char Ch)
|
jpayne@69
|
88
|
jpayne@69
|
89 /* Returns the DNA complement of Ch . */
|
jpayne@69
|
90
|
jpayne@69
|
91 {
|
jpayne@69
|
92 switch (tolower (Ch))
|
jpayne@69
|
93 {
|
jpayne@69
|
94 case 'a' :
|
jpayne@69
|
95 return 't';
|
jpayne@69
|
96 case 'c' :
|
jpayne@69
|
97 return 'g';
|
jpayne@69
|
98 case 'g' :
|
jpayne@69
|
99 return 'c';
|
jpayne@69
|
100 case 't' :
|
jpayne@69
|
101 return 'a';
|
jpayne@69
|
102 case 'r' : // a or g
|
jpayne@69
|
103 return 'y';
|
jpayne@69
|
104 case 'y' : // c or t
|
jpayne@69
|
105 return 'r';
|
jpayne@69
|
106 case 's' : // c or g
|
jpayne@69
|
107 return 's';
|
jpayne@69
|
108 case 'w' : // a or t
|
jpayne@69
|
109 return 'w';
|
jpayne@69
|
110 case 'm' : // a or c
|
jpayne@69
|
111 return 'k';
|
jpayne@69
|
112 case 'k' : // g or t
|
jpayne@69
|
113 return 'm';
|
jpayne@69
|
114 case 'b' : // c, g or t
|
jpayne@69
|
115 return 'v';
|
jpayne@69
|
116 case 'd' : // a, g or t
|
jpayne@69
|
117 return 'h';
|
jpayne@69
|
118 case 'h' : // a, c or t
|
jpayne@69
|
119 return 'd';
|
jpayne@69
|
120 case 'v' : // a, c or g
|
jpayne@69
|
121 return 'b';
|
jpayne@69
|
122 default : // anything
|
jpayne@69
|
123 return tolower (Ch);
|
jpayne@69
|
124 }
|
jpayne@69
|
125 }
|
jpayne@69
|
126
|
jpayne@69
|
127
|
jpayne@69
|
128 bool CompareIUPAC (char x, char y)
|
jpayne@69
|
129 {
|
jpayne@69
|
130 x = tolower(x);
|
jpayne@69
|
131 y = tolower(y);
|
jpayne@69
|
132
|
jpayne@69
|
133 if ( x == 'n' || x == 'x' || y == 'n' || y == 'x' )
|
jpayne@69
|
134 return true;
|
jpayne@69
|
135
|
jpayne@69
|
136 switch ( x )
|
jpayne@69
|
137 {
|
jpayne@69
|
138 case 'a' :
|
jpayne@69
|
139 switch ( y )
|
jpayne@69
|
140 {
|
jpayne@69
|
141 case 'a':
|
jpayne@69
|
142 case 'r':
|
jpayne@69
|
143 case 'w':
|
jpayne@69
|
144 case 'm':
|
jpayne@69
|
145 case 'd':
|
jpayne@69
|
146 case 'h':
|
jpayne@69
|
147 case 'v':
|
jpayne@69
|
148 return true;
|
jpayne@69
|
149 }
|
jpayne@69
|
150 return false;
|
jpayne@69
|
151
|
jpayne@69
|
152 case 'c' :
|
jpayne@69
|
153 switch ( y )
|
jpayne@69
|
154 {
|
jpayne@69
|
155 case 'c':
|
jpayne@69
|
156 case 'y':
|
jpayne@69
|
157 case 's':
|
jpayne@69
|
158 case 'm':
|
jpayne@69
|
159 case 'b':
|
jpayne@69
|
160 case 'h':
|
jpayne@69
|
161 case 'v':
|
jpayne@69
|
162 return true;
|
jpayne@69
|
163 }
|
jpayne@69
|
164 return false;
|
jpayne@69
|
165
|
jpayne@69
|
166 case 'g' :
|
jpayne@69
|
167 switch ( y )
|
jpayne@69
|
168 {
|
jpayne@69
|
169 case 'g':
|
jpayne@69
|
170 case 'r':
|
jpayne@69
|
171 case 's':
|
jpayne@69
|
172 case 'k':
|
jpayne@69
|
173 case 'b':
|
jpayne@69
|
174 case 'd':
|
jpayne@69
|
175 case 'v':
|
jpayne@69
|
176 return true;
|
jpayne@69
|
177 }
|
jpayne@69
|
178 return false;
|
jpayne@69
|
179
|
jpayne@69
|
180 case 't' :
|
jpayne@69
|
181 switch ( y )
|
jpayne@69
|
182 {
|
jpayne@69
|
183 case 't':
|
jpayne@69
|
184 case 'y':
|
jpayne@69
|
185 case 'w':
|
jpayne@69
|
186 case 'k':
|
jpayne@69
|
187 case 'b':
|
jpayne@69
|
188 case 'd':
|
jpayne@69
|
189 case 'h':
|
jpayne@69
|
190 return true;
|
jpayne@69
|
191 }
|
jpayne@69
|
192 return false;
|
jpayne@69
|
193
|
jpayne@69
|
194 case 'r' : // a or g
|
jpayne@69
|
195 switch ( y )
|
jpayne@69
|
196 {
|
jpayne@69
|
197 case 'r':
|
jpayne@69
|
198 case 'a':
|
jpayne@69
|
199 case 'g':
|
jpayne@69
|
200 case 'd':
|
jpayne@69
|
201 case 'v':
|
jpayne@69
|
202 return true;
|
jpayne@69
|
203 }
|
jpayne@69
|
204 return false;
|
jpayne@69
|
205
|
jpayne@69
|
206 case 'y' : // c or t
|
jpayne@69
|
207 switch ( y )
|
jpayne@69
|
208 {
|
jpayne@69
|
209 case 'y':
|
jpayne@69
|
210 case 'c':
|
jpayne@69
|
211 case 't':
|
jpayne@69
|
212 case 'b':
|
jpayne@69
|
213 case 'h':
|
jpayne@69
|
214 return true;
|
jpayne@69
|
215 }
|
jpayne@69
|
216 return false;
|
jpayne@69
|
217
|
jpayne@69
|
218 case 's' : // c or g
|
jpayne@69
|
219 switch ( y )
|
jpayne@69
|
220 {
|
jpayne@69
|
221 case 's':
|
jpayne@69
|
222 case 'c':
|
jpayne@69
|
223 case 'g':
|
jpayne@69
|
224 case 'b':
|
jpayne@69
|
225 case 'v':
|
jpayne@69
|
226 return true;
|
jpayne@69
|
227 }
|
jpayne@69
|
228 return false;
|
jpayne@69
|
229
|
jpayne@69
|
230 case 'w' : // a or t
|
jpayne@69
|
231 switch ( y )
|
jpayne@69
|
232 {
|
jpayne@69
|
233 case 'w':
|
jpayne@69
|
234 case 'a':
|
jpayne@69
|
235 case 't':
|
jpayne@69
|
236 case 'd':
|
jpayne@69
|
237 case 'h':
|
jpayne@69
|
238 return true;
|
jpayne@69
|
239 }
|
jpayne@69
|
240 return false;
|
jpayne@69
|
241
|
jpayne@69
|
242 case 'm' : // a or c
|
jpayne@69
|
243 switch ( y )
|
jpayne@69
|
244 {
|
jpayne@69
|
245 case 'm':
|
jpayne@69
|
246 case 'a':
|
jpayne@69
|
247 case 'c':
|
jpayne@69
|
248 case 'h':
|
jpayne@69
|
249 case 'v':
|
jpayne@69
|
250 return true;
|
jpayne@69
|
251 }
|
jpayne@69
|
252 return false;
|
jpayne@69
|
253
|
jpayne@69
|
254 case 'k' : // g or t
|
jpayne@69
|
255 switch ( y )
|
jpayne@69
|
256 {
|
jpayne@69
|
257 case 'k':
|
jpayne@69
|
258 case 'g':
|
jpayne@69
|
259 case 't':
|
jpayne@69
|
260 case 'b':
|
jpayne@69
|
261 case 'd':
|
jpayne@69
|
262 return true;
|
jpayne@69
|
263 }
|
jpayne@69
|
264 return false;
|
jpayne@69
|
265
|
jpayne@69
|
266 case 'b' : // c, g or t
|
jpayne@69
|
267 switch ( y )
|
jpayne@69
|
268 {
|
jpayne@69
|
269 case 'b':
|
jpayne@69
|
270 case 'c':
|
jpayne@69
|
271 case 'g':
|
jpayne@69
|
272 case 't':
|
jpayne@69
|
273 return true;
|
jpayne@69
|
274 }
|
jpayne@69
|
275 return false;
|
jpayne@69
|
276
|
jpayne@69
|
277 case 'd' : // a, g or t
|
jpayne@69
|
278 switch ( y )
|
jpayne@69
|
279 {
|
jpayne@69
|
280 case 'd':
|
jpayne@69
|
281 case 'a':
|
jpayne@69
|
282 case 'g':
|
jpayne@69
|
283 case 't':
|
jpayne@69
|
284 return true;
|
jpayne@69
|
285 }
|
jpayne@69
|
286 return false;
|
jpayne@69
|
287
|
jpayne@69
|
288 case 'h' : // a, c or t
|
jpayne@69
|
289 switch ( y )
|
jpayne@69
|
290 {
|
jpayne@69
|
291 case 'h':
|
jpayne@69
|
292 case 'a':
|
jpayne@69
|
293 case 'c':
|
jpayne@69
|
294 case 't':
|
jpayne@69
|
295 return true;
|
jpayne@69
|
296 }
|
jpayne@69
|
297 return false;
|
jpayne@69
|
298
|
jpayne@69
|
299 case 'v' : // a, c or g
|
jpayne@69
|
300 switch ( y )
|
jpayne@69
|
301 {
|
jpayne@69
|
302 case 'v':
|
jpayne@69
|
303 case 'a':
|
jpayne@69
|
304 case 'c':
|
jpayne@69
|
305 case 'g':
|
jpayne@69
|
306 return true;
|
jpayne@69
|
307 }
|
jpayne@69
|
308 return false;
|
jpayne@69
|
309 }
|
jpayne@69
|
310 return false;
|
jpayne@69
|
311 }
|
jpayne@69
|
312
|
jpayne@69
|
313
|
jpayne@69
|
314 int Read_String (FILE * fp, char * & T, long int & Size, char Name [],
|
jpayne@69
|
315 int Partial)
|
jpayne@69
|
316
|
jpayne@69
|
317 /* Read next string from fp (assuming FASTA format) into T [1 ..]
|
jpayne@69
|
318 * which has Size characters. Allocate extra memory if needed
|
jpayne@69
|
319 * and adjust Size accordingly. Return TRUE if successful, FALSE
|
jpayne@69
|
320 * otherwise (e.g., EOF). Partial indicates if first line has
|
jpayne@69
|
321 * numbers indicating a subrange of characters to read.
|
jpayne@69
|
322 */
|
jpayne@69
|
323
|
jpayne@69
|
324 {
|
jpayne@69
|
325 char * P, Line [MAX_LINE];
|
jpayne@69
|
326 long int Len, Lo, Hi;
|
jpayne@69
|
327 int Ch, Ct;
|
jpayne@69
|
328
|
jpayne@69
|
329 while ((Ch = fgetc (fp)) != EOF && Ch != '>')
|
jpayne@69
|
330 ;
|
jpayne@69
|
331
|
jpayne@69
|
332 if (Ch == EOF)
|
jpayne@69
|
333 return FALSE;
|
jpayne@69
|
334
|
jpayne@69
|
335 fgets (Line, MAX_LINE, fp);
|
jpayne@69
|
336 Len = strlen (Line);
|
jpayne@69
|
337 assert (Len > 0 && Line [Len - 1] == '\n');
|
jpayne@69
|
338 P = strtok (Line, " \t\n");
|
jpayne@69
|
339 if (P != NULL)
|
jpayne@69
|
340 strcpy (Name, P);
|
jpayne@69
|
341 else
|
jpayne@69
|
342 Name [0] = '\0';
|
jpayne@69
|
343 Lo = 0; Hi = LONG_MAX;
|
jpayne@69
|
344 if (Partial)
|
jpayne@69
|
345 {
|
jpayne@69
|
346 P = strtok (NULL, " \t\n");
|
jpayne@69
|
347 if (P != NULL)
|
jpayne@69
|
348 {
|
jpayne@69
|
349 Lo = strtol (P, NULL, 10);
|
jpayne@69
|
350 P = strtok (NULL, " \t\n");
|
jpayne@69
|
351 if (P != NULL)
|
jpayne@69
|
352 Hi = strtol (P, NULL, 10);
|
jpayne@69
|
353 }
|
jpayne@69
|
354 assert (Lo <= Hi);
|
jpayne@69
|
355 }
|
jpayne@69
|
356
|
jpayne@69
|
357 Ct = 0;
|
jpayne@69
|
358 T [0] = '\0';
|
jpayne@69
|
359 Len = 1;
|
jpayne@69
|
360 while ((Ch = fgetc (fp)) != EOF && Ch != '>')
|
jpayne@69
|
361 {
|
jpayne@69
|
362 if (isspace (Ch))
|
jpayne@69
|
363 continue;
|
jpayne@69
|
364
|
jpayne@69
|
365 Ct ++;
|
jpayne@69
|
366 if (Ct < Lo || Ct > Hi)
|
jpayne@69
|
367 continue;
|
jpayne@69
|
368
|
jpayne@69
|
369 if (Len >= Size)
|
jpayne@69
|
370 {
|
jpayne@69
|
371 Size += INCR_SIZE;
|
jpayne@69
|
372 T = (char *) Safe_realloc (T, Size);
|
jpayne@69
|
373 }
|
jpayne@69
|
374 Ch = tolower (Ch);
|
jpayne@69
|
375
|
jpayne@69
|
376 if (! isalpha (Ch) && Ch != '*')
|
jpayne@69
|
377 {
|
jpayne@69
|
378 fprintf (stderr, "Unexpected character `%c\' in string %s\n",
|
jpayne@69
|
379 Ch, Name);
|
jpayne@69
|
380 Ch = 'x';
|
jpayne@69
|
381 }
|
jpayne@69
|
382
|
jpayne@69
|
383 T [Len ++] = Ch;
|
jpayne@69
|
384 }
|
jpayne@69
|
385
|
jpayne@69
|
386 T [Len] = '\0';
|
jpayne@69
|
387 if (Ch == '>')
|
jpayne@69
|
388 ungetc (Ch, fp);
|
jpayne@69
|
389
|
jpayne@69
|
390 return TRUE;
|
jpayne@69
|
391 }
|
jpayne@69
|
392
|
jpayne@69
|
393
|
jpayne@69
|
394
|
jpayne@69
|
395 void Reverse_Complement
|
jpayne@69
|
396 (char S [], long int Lo, long int Hi)
|
jpayne@69
|
397
|
jpayne@69
|
398 // Convert substring S [Lo .. Hi] to its Watson-Crick reverse
|
jpayne@69
|
399 // complement
|
jpayne@69
|
400
|
jpayne@69
|
401 {
|
jpayne@69
|
402 char Ch;
|
jpayne@69
|
403
|
jpayne@69
|
404 while (Lo <= Hi)
|
jpayne@69
|
405 {
|
jpayne@69
|
406 Ch = S [Hi];
|
jpayne@69
|
407 S [Hi] = Complement (S [Lo]);
|
jpayne@69
|
408 S [Lo] = Complement (Ch);
|
jpayne@69
|
409 Lo ++;
|
jpayne@69
|
410 Hi --;
|
jpayne@69
|
411 }
|
jpayne@69
|
412
|
jpayne@69
|
413 return;
|
jpayne@69
|
414 }
|
jpayne@69
|
415
|