source: tags/arb_5.2/READSEQ/ureadseq.c

Last change on this file was 6287, checked in by westram, 14 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 52.2 KB
Line 
1/* File: ureadseq.c
2 *
3 * Reads and writes nucleic/protein sequence in various
4 * formats. Data files may have multiple sequences.
5 *
6 * Copyright 1990 by d.g.gilbert
7 * biology dept., indiana university, bloomington, in 47405
8 * e-mail: gilbertd@bio.indiana.edu
9 *
10 * This program may be freely copied and used by anyone.
11 * Developers are encourged to incorporate parts in their
12 * programs, rather than devise their own private sequence
13 * format.
14 *
15 * This should compile and run with any ANSI C compiler.
16 *
17 * ------------------------------------------------------------
18 *
19 * Some slight modifications were done by ARB developers
20 *
21 */
22
23
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#define __NO_CTYPE
28#include <ctype.h>
29
30#include "ureadseq.h"
31prettyopts  gPretty;
32
33#pragma segment ureadseq
34
35
36int Strcasecmp(const char *a, const char *b)  /* from Nlm_StrICmp */
37{
38  int diff, done;
39  if (a == b)  return 0;
40  done = 0;
41  while (! done) {
42    diff = to_upper(*a) - to_upper(*b);
43    if (diff) return diff;
44    if (*a == '\0') done = 1;
45    else { a++; b++; }
46    }
47  return 0;
48}
49
50int Strncasecmp(const char *a, const char *b, long maxn) /* from Nlm_StrNICmp */
51{
52  int diff, done;
53  if (a == b)  return 0;
54  done = 0;
55  while (! done) {
56    diff = to_upper(*a) - to_upper(*b);
57    if (diff) return diff;
58    if (*a == '\0') done = 1;
59    else {
60      a++; b++; maxn--;
61      if (! maxn) done = 1;
62      }
63    }
64  return 0;
65}
66
67
68
69
70
71#ifndef Local
72# define Local static /* local functions */
73#endif
74
75#define kStartLength  500000   /* 20Apr93 temp. bug fix */
76
77const char *aminos      = "ABCDEFGHIKLMNPQRSTVWXYZ*";
78const char *primenuc    = "ACGTU";
79const char *protonly    = "EFIPQZ";
80
81const char kNocountsymbols[5]  = "_.-?";
82const char stdsymbols[6]  = "_.-*?";
83const char allsymbols[32] = "_.-*?<>{}[]()!@#$%^&=+;:'/|`~\"\\";
84static const char *seqsymbols   = allsymbols;
85
86const char nummask[11]   = "0123456789";
87const char nonummask[11] = "~!@#$%^&*(";
88
89/*
90    use general form of isseqchar -- all chars + symbols.
91    no formats except nbrf (?) use symbols in data area as
92    anything other than sequence chars.
93*/
94
95
96
97                          /* Local variables for readSeq: */
98struct ReadSeqVars {
99  short choice, err, nseq;
100  long  seqlen, maxseq, seqlencount;
101  short topnseq;
102  long  topseqlen;
103  const char *fname;
104  char *seq, *seqid, matchchar;
105  boolean allDone, done, filestart, addit;
106  FILE  *f;
107  long  linestart;
108  char  s[256], *sp;
109
110  int (*isseqcharfirst8)(); /* Patch by o. strunk (ARB) to allow numbers in genbank sequences*/
111  int (*isseqchar)();
112  /* int  (*isseqchar)(int c);  << sgi cc hates (int c) */
113};
114
115
116
117int isSeqChar(int c)
118{
119  return (isalpha(c) || strchr(seqsymbols,c));
120}
121
122int isSeqNumChar(int c)
123{
124  return (isalnum(c) || strchr(seqsymbols,c));
125}
126
127
128int isAnyChar(int c)
129{
130  return isascii(c); /* wrap in case isascii is macro */
131}
132
133Local void readline(FILE *f, char *s, long *linestart)
134{
135  char  *cp;
136
137  *linestart= ftell(f);
138  if (NULL == fgets(s, 256, f))
139    *s = 0;
140  else {
141    cp = strchr(s, '\n');
142    if (cp != NULL) *cp = 0;
143    }
144}
145
146Local void GetLine(struct ReadSeqVars *V)
147{
148  readline(V->f, V->s, &V->linestart);
149}
150
151Local void unGetLine(struct ReadSeqVars *V)
152{
153  fseek(V->f, V->linestart, 0);
154}
155
156
157Local void addseq(char *s, struct ReadSeqVars * V)
158{
159    char *ptr;
160    int   count = 0;
161    if (V->addit) {
162        for  (;*s != 0;s++,count++) {
163            if (count < 9 && V->isseqcharfirst8) {
164                if (!(V->isseqcharfirst8) (*s)) continue;
165            }else{
166                if (!(V->isseqchar) (*s)) continue;
167            }
168            if (V->seqlen >= V->maxseq) {
169                V->maxseq += kStartLength;
170                ptr = (char *) realloc(V->seq, V->maxseq + 1);
171                if (ptr == NULL) {
172                    V->err = eMemFull;
173                    return;
174                } else
175                    V->seq = ptr;
176            }
177            V->seq[(V->seqlen)++] = *s;
178        }
179    }
180}
181
182Local void countseq(char *s, struct ReadSeqVars *V)
183 /* this must count all valid seq chars, for some formats (paup-sequential) even
184    if we are skipping seq... */
185{
186  while (*s != 0) {
187    if ((V->isseqchar)(*s)) {
188      (V->seqlencount)++;
189      }
190    s++;
191    }
192}
193
194
195Local void addinfo(char *s, struct ReadSeqVars *V)
196{
197  char s2[256], *si;
198  boolean saveadd;
199
200  si = s2;
201  while (*s == ' ') s++;
202  sprintf(si, " %d)  %s\n", V->nseq, s);
203
204  saveadd = V->addit;
205  V->addit = true;
206  V->isseqchar = isAnyChar;
207  addseq( si, V);
208  V->addit = saveadd;
209  V->isseqchar = isSeqChar;
210}
211
212
213
214
215Local void readLoop(short margin, boolean addfirst,
216            boolean (*endTest)(boolean *addend, boolean *ungetend, struct ReadSeqVars *V),
217            struct ReadSeqVars *V)
218{
219  boolean addend = false;
220  boolean ungetend = false;
221
222  V->nseq++;
223  if (V->choice == kListSequences) V->addit = false;
224  else V->addit = (V->nseq == V->choice);
225  if (V->addit) V->seqlen = 0;
226
227  if (addfirst) addseq(V->s, V);
228  do {
229    GetLine(V);
230    V->done = feof(V->f);
231    V->done |= (*endTest)( &addend, &ungetend, V);
232    if (V->addit && (addend || !V->done) && (strlen(V->s) > (unsigned)margin)) {
233      addseq( (V->s)+margin, V);
234    }
235  } while (!V->done);
236
237  if (V->choice == kListSequences) addinfo(V->seqid, V);
238  else {
239    V->allDone = (V->nseq >= V->choice);
240    if (V->allDone && ungetend) unGetLine(V);
241    }
242}
243
244
245
246Local boolean endIG( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
247{
248  *addend = true; /* 1 or 2 occur in line w/ bases */
249  *ungetend= false;
250  return((strchr(V->s,'1')!=NULL) || (strchr(V->s,'2')!=NULL));
251}
252
253Local void readIG(struct ReadSeqVars *V)
254{
255/* 18Aug92: new IG format -- ^L between sequences in place of ";" */
256  char  *si;
257
258  while (!V->allDone) {
259    do {
260      GetLine(V);
261      for (si= V->s; *si != 0 && *si < ' '; si++) *si= ' '; /* drop controls */
262      if (*si == 0) *V->s= 0; /* chop line to empty */
263    } while (! (feof(V->f) || ((*V->s != 0) && (*V->s != ';') ) ));
264    if (feof(V->f))
265      V->allDone = true;
266    else {
267      strcpy(V->seqid, V->s);
268      readLoop(0, false, endIG, V);
269      }
270  }
271}
272
273
274
275Local boolean endStrider( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
276{
277  *addend = false;
278  *ungetend= false;
279  return (strstr( V->s, "//") != NULL);
280}
281
282Local void readStrider(struct ReadSeqVars *V)
283{ /* ? only 1 seq/file ? */
284
285  while (!V->allDone) {
286    GetLine(V);
287    if (strstr(V->s,"; DNA sequence  ") == V->s)
288      strcpy(V->seqid, (V->s)+16);
289    else
290      strcpy(V->seqid, (V->s)+1);
291    while ((!feof(V->f)) && (*V->s == ';')) {
292      GetLine(V);
293      }
294    if (feof(V->f)) V->allDone = true;
295    else readLoop(0, true, endStrider, V);
296  }
297}
298
299
300Local boolean endPIR( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
301{
302  *addend = false;
303  *ungetend= (strstr(V->s,"ENTRY") == V->s);
304  return ((strstr(V->s,"///") != NULL) || *ungetend);
305}
306
307Local void readPIR(struct ReadSeqVars *V)
308{ /*PIR -- many seqs/file */
309
310  while (!V->allDone) {
311    while (! (feof(V->f) || strstr(V->s,"ENTRY")  || strstr(V->s,"SEQUENCE")) )
312      GetLine(V);
313    strcpy(V->seqid, (V->s)+16);
314    while (! (feof(V->f) || strstr(V->s,"SEQUENCE") == V->s))
315      GetLine(V);
316    readLoop(0, false, endPIR, V);
317
318    if (!V->allDone) {
319     while (! (feof(V->f) || ((*V->s != 0)
320       && (strstr( V->s,"ENTRY") == V->s))))
321        GetLine(V);
322      }
323    if (feof(V->f)) V->allDone = true;
324  }
325}
326
327
328Local boolean endGB( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
329{
330  *addend = false;
331  *ungetend= (strstr(V->s,"LOCUS") == V->s);
332  return ((strstr(V->s,"//") != NULL) || *ungetend);
333}
334
335Local void readGenBank(struct ReadSeqVars * V)
336{ /* GenBank -- many seqs/file */
337
338  V->isseqchar       = isSeqNumChar;
339  V->isseqcharfirst8 = isSeqChar;
340
341  while (!V->allDone) {
342    strcpy(V->seqid, (V->s)+12);
343    while (! (feof(V->f) || strstr(V->s,"ORIGIN") == V->s))
344      GetLine(V);
345    readLoop(0, false, endGB, V);
346
347    if (!V->allDone) {
348     while (! (feof(V->f) || ((*V->s != 0)
349       && (strstr( V->s, "LOCUS") == V->s))))
350        GetLine(V);
351      }
352    if (feof(V->f)) V->allDone = true;
353  }
354
355  V->isseqchar = isSeqChar;
356  V->isseqcharfirst8 = 0;
357}
358
359
360Local boolean endNBRF( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
361{
362  char  *a;
363
364  if ((a = strchr(V->s, '*')) != NULL) { /* end of 1st seq */
365    /* "*" can be valid base symbol, drop it here */
366    *a = 0;
367    *addend = true;
368    *ungetend= false;
369    return(true);
370    }
371  else if (*V->s == '>') { /* start of next seq */
372    *addend = false;
373    *ungetend= true;
374    return(true);
375    }
376  else
377    return(false);
378}
379
380Local void readNBRF(struct ReadSeqVars *V)
381{
382  while (!V->allDone) {
383    strcpy(V->seqid, (V->s)+4);
384    GetLine(V);   /*skip title-junk line*/
385    readLoop(0, false, endNBRF, V);
386    if (!V->allDone) {
387     while (!(feof(V->f) || (*V->s != 0 && *V->s == '>')))
388        GetLine(V);
389      }
390    if (feof(V->f)) V->allDone = true;
391  }
392}
393
394
395
396Local boolean endPearson( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
397{
398  *addend = false;
399  *ungetend= true;
400  return(*V->s == '>');
401}
402
403Local void readPearson(struct ReadSeqVars *V)
404{
405  while (!V->allDone) {
406    strcpy(V->seqid, (V->s)+1);
407    readLoop(0, false, endPearson, V);
408    if (!V->allDone) {
409     while (!(feof(V->f) || ((*V->s != 0) && (*V->s == '>'))))
410        GetLine(V);
411      }
412    if (feof(V->f)) V->allDone = true;
413  }
414}
415
416
417
418Local boolean endEMBL( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
419{
420  *addend = false;
421  *ungetend= (strstr(V->s,"ID   ") == V->s);
422  return ((strstr(V->s,"//") != NULL) || *ungetend);
423}
424
425Local void readEMBL(struct ReadSeqVars *V)
426{
427  while (!V->allDone) {
428    strcpy(V->seqid, (V->s)+5);
429    do {
430      GetLine(V);
431    } while (!(feof(V->f) | (strstr(V->s,"SQ   ") == V->s)));
432
433    readLoop(0, false, endEMBL, V);
434    if (!V->allDone) {
435      while (!(feof(V->f) |
436         ((*V->s != '\0') & (strstr(V->s,"ID   ") == V->s))))
437      GetLine(V);
438    }
439    if (feof(V->f)) V->allDone = true;
440  }
441}
442
443
444
445Local boolean endZuker( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
446{
447  *addend = false;
448  *ungetend= true;
449  return( *V->s == '(' );
450}
451
452Local void readZuker(struct ReadSeqVars *V)
453{
454  /*! 1st string is Zuker's Fortran format */
455
456  while (!V->allDone) {
457    GetLine(V);  /*s == "seqLen seqid string..."*/
458    strcpy(V->seqid, (V->s)+6);
459    readLoop(0, false, endZuker, V);
460    if (!V->allDone) {
461      while (!(feof(V->f) |
462        ((*V->s != '\0') & (*V->s == '('))))
463          GetLine(V);
464      }
465    if (feof(V->f)) V->allDone = true;
466  }
467}
468
469
470
471Local boolean endFitch( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
472{
473  /* this is a somewhat shaky end,
474    1st char of line is non-blank for seq. title
475  */
476  *addend = false;
477  *ungetend= true;
478  return( *V->s != ' ' );
479}
480
481Local void readFitch(struct ReadSeqVars *V)
482{
483  boolean first;
484
485  first = true;
486  while (!V->allDone) {
487    if (!first) strcpy(V->seqid, V->s);
488    readLoop(0, first, endFitch, V);
489    if (feof(V->f)) V->allDone = true;
490    first = false;
491    }
492}
493
494
495Local void readPlain(struct ReadSeqVars *V)
496{
497  V->nseq++;
498  V->addit = (V->choice > 0);
499  if (V->addit) V->seqlen = 0;
500  addseq(V->seqid, V);   /*from above..*/
501  if (V->fname!=NULL) sprintf(V->seqid, "%s  [Unknown form]", V->fname);
502  else sprintf(V->seqid, "  [Unknown form]");
503  do {
504    addseq(V->s, V);
505    V->done = feof(V->f);
506    GetLine(V);
507  } while (!V->done);
508  if (V->choice == kListSequences) addinfo(V->seqid, V);
509  V->allDone = true;
510}
511
512
513Local void readUWGCG(struct ReadSeqVars *V)
514{
515/*
51610nov91: Reading GCG files casued duplication of last line when
517         EOF followed that line !!!
518    fix: GetLine now sets *V->s = 0
519*/
520  char  *si;
521
522  V->nseq++;
523  V->addit = (V->choice > 0);
524  if (V->addit) V->seqlen = 0;
525  strcpy(V->seqid, V->s);
526  /*writeseq: "    %s  Length: %d  (today)  Check: %d  ..\n" */
527  /*drop above or ".." from id*/
528  if ((si = strstr(V->seqid,"  Length: "))) *si = 0;
529  else if ((si = strstr(V->seqid,".."))) *si = 0;
530  do {
531    V->done = feof(V->f);
532    GetLine(V);
533    if (!V->done) addseq((V->s), V);
534  } while (!V->done);
535  if (V->choice == kListSequences) addinfo(V->seqid, V);
536  V->allDone = true;
537}
538
539
540Local void readOlsen(struct ReadSeqVars *V)
541{ /* G. Olsen /print output from multiple sequence editor */
542
543  char    *si, *sj, *sk, *sm, sid[40], snum[20];
544  boolean indata = false;
545  int snumlen;
546
547  V->addit = (V->choice > 0);
548  if (V->addit) V->seqlen = 0;
549  rewind(V->f); V->nseq= 0;
550  do {
551    GetLine(V);
552    V->done = feof(V->f);
553
554    if (V->done && !(*V->s)) break;
555    else if (indata) {
556      if ( (si= strstr(V->s, sid))
557        /* && (strstr(V->s, snum) == si - snumlen - 1) ) { */
558        && (sm= strstr(V->s, snum)) && (sm < si - snumlen) ) {
559
560        /* Spaces are valid alignment data !! */
561/* 17Oct91: Error, the left margin is 21 not 22! */
562/* dropped some nucs up to now -- my example file was right shifted ! */
563/* variable right id margin, drop id-2 spaces at end */
564/*
565  VMS CC COMPILER (VAXC031) mess up:
566  -- Index of 21 is chopping 1st nuc on VMS systems Only!
567  Byte-for-byte same ame rnasep.olsen sequence file !
568*/
569
570        /* si = (V->s)+21; < was this before VMS CC wasted my time */
571        si += 10;  /* use strstr index plus offset to outfox VMS CC bug */
572
573        if ((sk = strstr(si, sid))) *(sk-2) = 0;
574        for (sk = si; *sk != 0; sk++) {
575           if (*sk == ' ') *sk = '.';
576           /* 18aug92: !! some olsen masks are NUMBERS !! which addseq eats */
577           else if (isdigit(*sk)) *sk= nonummask[*sk - '0'];
578           }
579
580        addseq(si, V);
581        }
582      }
583
584    else if ((sk = strstr(V->s, "): "))) {  /* seq info header line */
585  /* 18aug92: correct for diff seqs w/ same name -- use number, e.g. */
586  /*   3 (Agr.tume):  agrobacterium.prna  18-JUN-1987 16:12 */
587  /* 328 (Agr.tume):  agrobacterium.prna XYZ  19-DEC-1992   */
588      (V->nseq)++;
589      si = 1 + strchr(V->s,'(');
590      *sk = ' ';
591      if (V->choice == kListSequences) addinfo( si, V);
592      else if (V->nseq == V->choice) {
593        strcpy(V->seqid, si);
594        sj = strchr(V->seqid, ':');
595        while (*(--sj) == ' ') ;
596        while (--sj != V->seqid) { if (*sj == ' ') *sj = '_'; }
597
598        *sk = 0;
599        while (*(--sk) == ' ') *sk = 0;
600        strcpy(sid, si);
601
602        si= V->s;
603        while ((*si <= ' ') && (*si != 0)) si++;
604        snumlen=0;
605        while (si[snumlen] > ' ' && snumlen<20)
606         { snum[snumlen]= si[snumlen]; snumlen++; }
607        snum[snumlen]= 0;
608        }
609
610      }
611
612    else if (strstr(V->s,"identity:   Data:")) {
613      indata = true;
614      if (V->choice == kListSequences) V->done = true;
615      }
616
617  } while (!V->done);
618
619  V->allDone = true;
620} /*readOlsen*/
621
622
623Local void readMSF(struct ReadSeqVars *V)
624{ /* gcg's MSF, mult. sequence format, interleaved ! */
625
626  char    *si, *sj, sid[128];
627  boolean indata = false;
628  int     iline= 0;
629
630  V->addit = (V->choice > 0);
631  if (V->addit) V->seqlen = 0;
632  rewind(V->f); V->nseq= 0;
633  do {
634    GetLine(V);
635    V->done = feof(V->f);
636
637    if (V->done && !(*V->s)) break;
638    else if (indata) {
639      /*somename  ...gpvedai .......t.. aaigr..vad tvgtgptnse aipaltaaet */
640      /*       E  gvenae.kgv tentna.tad fvaqpvylpe .nqt...... kv.affynrs */
641
642      si= V->s;
643      skipwhitespace(si);
644      /* for (sj= si; isalnum(*sj); sj++) ; bug -- cdelwiche uses "-", "_" and others in names*/
645      for (sj= si; *sj > ' '; sj++) ;
646      *sj= 0;
647      if ( *si ) {
648        if ( (0==strcmp(si, sid)) ) {
649          addseq(sj+1, V);
650          }
651        iline++;
652        }
653      }
654
655    else if (NULL != (si = strstr(V->s, "Name: "))) {  /* seq info header line */
656      /* Name: somename      Len:   100  Check: 7009  Weight:  1.00 */
657
658      (V->nseq)++;
659      si += 6;
660      if (V->choice == kListSequences) addinfo( si, V);
661      else if (V->nseq == V->choice) {
662        strcpy(V->seqid, si);
663        si = V->seqid;
664        skipwhitespace(si);
665        /* for (sj= si; isalnum(*sj); sj++) ; -- bug */
666        for (sj= si; *sj > ' '; sj++) ;
667        *sj= 0;
668        strcpy(sid, si);
669        }
670      }
671
672    else if ( strstr(V->s,"//") /*== V->s*/ )  {
673      indata = true;
674      iline= 0;
675      if (V->choice == kListSequences) V->done = true;
676      }
677
678  } while (!V->done);
679
680
681  V->allDone = true;
682} /*readMSF*/
683
684
685
686Local void readPAUPinterleaved(struct ReadSeqVars *V)
687{ /* PAUP mult. sequence format, interleaved or sequential! */
688
689  char    *si, *sj, *send, sid[40], sid1[40], saveseq[255];
690  boolean first = true, indata = false, domatch;
691  int     iline= 0, ifmc, saveseqlen=0;
692
693#define fixmatchchar(s) { \
694  for (ifmc=0; ifmc<saveseqlen; ifmc++) \
695    if (s[ifmc] == V->matchchar) s[ifmc]= saveseq[ifmc]; }
696
697  V->addit = (V->choice > 0);
698  V->seqlencount = 0;
699  if (V->addit) V->seqlen = 0;
700  /* rewind(V->f); V->nseq= 0;  << do in caller !*/
701  indata= true; /* call here after we find "matrix" */
702  domatch= (V->matchchar > 0);
703
704  do {
705    GetLine(V);
706    V->done = feof(V->f);
707
708    if (V->done && !(*V->s)) break;
709    else if (indata) {
710      /* [         1                    1                    1         ]*/
711      /* human     aagcttcaccggcgcagtca ttctcataatcgcccacggR cttacatcct*/
712      /* chimp     ................a.t. .c.................a ..........*/
713      /* !! need to correct for V->matchchar */
714      si= V->s;
715      skipwhitespace(si);
716      if (strchr(si,';')) indata= false;
717
718      if (isalnum(*si))  {
719        /* valid data line starts w/ a left-justified seq name in columns [0..8] */
720        if (first) {
721          (V->nseq)++;
722          if (V->nseq >= V->topnseq) first= false;
723          for (sj = si; isalnum(*sj); sj++) ;
724          send= sj;
725          skipwhitespace(sj);
726          if (V->choice == kListSequences) {
727            *send= 0;
728            addinfo( si, V);
729            }
730          else if (V->nseq == V->choice) {
731            if (domatch) {
732              if (V->nseq == 1) { strcpy( saveseq, sj); saveseqlen= strlen(saveseq); }
733              else fixmatchchar( sj);
734              }
735            addseq(sj, V);
736            *send= 0;
737            strcpy(V->seqid, si);
738            strcpy(sid, si);
739            if (V->nseq == 1) strcpy(sid1, sid);
740            }
741          }
742
743        else if ( (strstr(si, sid) == si) ){
744          while (isalnum(*si)) si++;
745          skipwhitespace(si);
746          if (domatch) {
747            if (V->nseq == 1) { strcpy( saveseq, si); saveseqlen= strlen(saveseq); }
748            else fixmatchchar( si);
749            }
750          addseq(si, V);
751          }
752
753        else if (domatch && (strstr(si, sid1) == si)) {
754          strcpy( saveseq, si);
755          saveseqlen= strlen(saveseq);
756          }
757
758        iline++;
759        }
760      }
761
762    else if ( strstr(V->s,"matrix") )  {
763      indata = true;
764      iline= 0;
765      if (V->choice == kListSequences) V->done = true;
766      }
767
768  } while (!V->done);
769
770  V->allDone = true;
771} /*readPAUPinterleaved*/
772
773
774
775Local void readPAUPsequential(struct ReadSeqVars *V)
776{ /* PAUP mult. sequence format, interleaved or sequential! */
777  char    *si, *sj;
778  boolean atname = true, indata = false;
779
780  V->addit = (V->choice > 0);
781  if (V->addit) V->seqlen = 0;
782  V->seqlencount = 0;
783  /* rewind(V->f); V->nseq= 0;  << do in caller !*/
784  indata= true; /* call here after we find "matrix" */
785  do {
786    GetLine(V);
787    V->done = feof(V->f);
788
789    if (V->done && !(*V->s)) break;
790    else if (indata) {
791      /* [         1                    1                    1         ]*/
792      /* human     aagcttcaccggcgcagtca ttctcataatcgcccacggR cttacatcct*/
793      /*           aagcttcaccggcgcagtca ttctcataatcgcccacggR cttacatcct*/
794      /* chimp     ................a.t. .c.................a ..........*/
795      /*           ................a.t. .c.................a ..........*/
796
797      si= V->s;
798      skipwhitespace(si);
799      if (strchr(si,';')) indata= false;
800      if (isalnum(*si))  {
801        /* valid data line starts w/ a left-justified seq name in columns [0..8] */
802        if (atname) {
803          (V->nseq)++;
804          V->seqlencount = 0;
805          atname= false;
806          sj= si+1;
807          while (isalnum(*sj)) sj++;
808          if (V->choice == kListSequences) {
809            /* !! we must count bases to know when topseqlen is reached ! */
810            countseq(sj, V);
811            if (V->seqlencount >= V->topseqlen) atname= true;
812            *sj= 0;
813            addinfo( si, V);
814            }
815          else if (V->nseq == V->choice) {
816            addseq(sj, V);
817            V->seqlencount= V->seqlen;
818            if (V->seqlencount >= V->topseqlen) atname= true;
819            *sj= 0;
820            strcpy(V->seqid, si);
821            }
822          else {
823            countseq(sj, V);
824            if (V->seqlencount >= V->topseqlen) atname= true;
825            }
826          }
827
828        else if (V->nseq == V->choice) {
829          addseq(V->s, V);
830          V->seqlencount= V->seqlen;
831          if (V->seqlencount >= V->topseqlen) atname= true;
832          }
833        else {
834          countseq(V->s, V);
835          if (V->seqlencount >= V->topseqlen) atname= true;
836          }
837        }
838      }
839
840    else if ( strstr(V->s,"matrix") )  {
841      indata = true;
842      atname= true;
843      if (V->choice == kListSequences) V->done = true;
844      }
845
846  } while (!V->done);
847
848  V->allDone = true;
849} /*readPAUPsequential*/
850
851
852Local void readPhylipInterleaved(struct ReadSeqVars *V)
853{
854  char    *si, *sj;
855  boolean first = true;
856  int     iline= 0;
857
858  V->addit = (V->choice > 0);
859  if (V->addit) V->seqlen = 0;
860  V->seqlencount = 0;
861  /* sscanf( V->s, "%d%d", &V->topnseq, &V->topseqlen); << topnseq == 0 !!! bad scan !! */
862  si= V->s;
863  skipwhitespace(si);
864  V->topnseq= atoi(si);
865  while (isdigit(*si)) si++;
866  skipwhitespace(si);
867  V->topseqlen= atol(si);
868  /* fprintf(stderr,"Phylip-ileaf: topnseq=%d  topseqlen=%d\n",V->topnseq, V->topseqlen); */
869
870  do {
871    GetLine(V);
872    V->done = feof(V->f);
873
874    if (V->done && !(*V->s)) break;
875    si= V->s;
876    skipwhitespace(si);
877    if (*si != 0) {
878
879      if (first) {  /* collect seq names + seq, as fprintf(outf,"%-10s  ",seqname); */
880        (V->nseq)++;
881        if (V->nseq >= V->topnseq) first= false;
882        sj= V->s+10;  /* past name, start of data */
883        if (V->choice == kListSequences) {
884          *sj= 0;
885          addinfo( si, V);
886          }
887        else if (V->nseq == V->choice) {
888          addseq(sj, V);
889          *sj= 0;
890          strcpy(V->seqid, si);
891          }
892        }
893      else if ( iline % V->nseq == V->choice -1 ) {
894        addseq(si, V);
895        }
896      iline++;
897    }
898  } while (!V->done);
899
900  V->allDone = true;
901} /*readPhylipInterleaved*/
902
903
904
905Local boolean endPhylipSequential( boolean *addend, boolean *ungetend, struct ReadSeqVars *V)
906{
907  *addend = false;
908  *ungetend= false;
909  countseq( V->s, V);
910  return V->seqlencount >= V->topseqlen;
911}
912
913Local void readPhylipSequential(struct ReadSeqVars *V)
914{
915  short  i;
916  char  *si;
917  /* sscanf( V->s, "%d%d", &V->topnseq, &V->topseqlen); < ? bad sscan ? */
918  si= V->s;
919  skipwhitespace(si);
920  V->topnseq= atoi(si);
921  while (isdigit(*si)) si++;
922  skipwhitespace(si);
923  V->topseqlen= atol(si);
924  GetLine(V);
925  while (!V->allDone) {
926    V->seqlencount= 0;
927    strncpy(V->seqid, (V->s), 10);
928    V->seqid[10]= 0;
929    for (i=0; i<10 && V->s[i]; i++) V->s[i]= ' ';
930    readLoop(0, true, endPhylipSequential, V);
931    if (feof(V->f)) V->allDone = true;
932    }
933}
934
935
936
937
938Local void readSeqMain(
939      struct ReadSeqVars *V,
940      const long  skiplines_,
941      const short format_)
942{
943#define tolowerstr(s) { long Itlwr, Ntlwr= strlen(s); \
944  for (Itlwr=0; Itlwr<Ntlwr; Itlwr++) s[Itlwr]= to_lower(s[Itlwr]); }
945
946  boolean gotuw;
947  long l;
948
949  V->linestart= 0;
950  V->matchchar= 0;
951  if (V->f == NULL)
952    V->err = eFileNotFound;
953  else {
954
955    for (l = skiplines_; l > 0; l--) GetLine( V);
956
957    do {
958      GetLine( V);
959      for (l= strlen(V->s); (l > 0) && (V->s[l] == ' '); l--) ;
960    } while ((l == 0) && !feof(V->f));
961
962    if (feof(V->f)) V->err = eNoData;
963
964    else switch (format_) {
965      case kPlain : readPlain(V); break;
966      case kIG    : readIG(V); break;
967      case kStrider: readStrider(V); break;
968      case kGenBank: readGenBank(V); break;
969      case kPIR   : readPIR(V); break;
970      case kNBRF  : readNBRF(V); break;
971      case kPearson: readPearson(V); break;
972      case kEMBL  : readEMBL(V); break;
973      case kZuker : readZuker(V); break;
974      case kOlsen : readOlsen(V); break;
975      case kMSF   : readMSF(V); break;
976
977      case kPAUP    : {
978        boolean done= false;
979        boolean interleaved= false;
980        char  *cp;
981        /* rewind(V->f); V->nseq= 0; ?? assume it is at top ?? skiplines ... */
982        while (!done) {
983          GetLine( V);
984          tolowerstr( V->s);
985          if (strstr( V->s, "matrix")) done= true;
986          if (strstr( V->s, "interleav")) interleaved= true;
987          if (NULL != (cp=strstr( V->s, "ntax=")) )  V->topnseq= atoi(cp+5);
988          if (NULL != (cp=strstr( V->s, "nchar=")) )  V->topseqlen= atoi(cp+6);
989          if (NULL != (cp=strstr( V->s, "matchchar=")) )  {
990            cp += 10;
991            if (*cp=='\'') cp++;
992            else if (*cp=='"') cp++;
993            V->matchchar= *cp;
994            }
995          }
996        if (interleaved) readPAUPinterleaved(V);
997        else readPAUPsequential(V);
998        }
999        break;
1000
1001      /* kPhylip: ! can't determine in middle of file which type it is...*/
1002      /* test for interleave or sequential and use Phylip4(ileave) or Phylip2 */
1003      case kPhylip2:
1004        readPhylipSequential(V);
1005        break;
1006      case kPhylip4: /* == kPhylip3 */
1007        readPhylipInterleaved(V);
1008        break;
1009
1010      default:
1011        V->err = eUnknownFormat;
1012        break;
1013
1014      case kFitch :
1015        strcpy(V->seqid, V->s); GetLine(V);
1016        readFitch(V);
1017        break;
1018
1019      case kGCG:
1020        do {
1021          gotuw = (strstr(V->s,"..") != NULL);
1022          if (gotuw) readUWGCG(V);
1023          GetLine(V);
1024        } while (!(feof(V->f) || V->allDone));
1025        break;
1026      }
1027    }
1028
1029  V->filestart= false;
1030  V->seq[V->seqlen] = 0; /* stick a string terminator on it */
1031}
1032
1033
1034char *readSeqFp(
1035      const short whichEntry_,  /* index to sequence in file */
1036      FILE  *fp_,   /* pointer to open seq file */
1037      const long  skiplines_,
1038      const short format_,      /* sequence file format */
1039      long  *seqlen_,     /* return seq size */
1040      short *nseq_,       /* number of seqs in file, for listSeqs() */
1041      short *error_,      /* return error */
1042      char  *seqid_)      /* return seq name/info */
1043{
1044  struct ReadSeqVars V;
1045
1046  if (format_ < kMinFormat || format_ > kMaxFormat) {
1047    *error_ = eUnknownFormat;
1048    *seqlen_ = 0;
1049    return NULL;
1050    }
1051
1052  V.choice = whichEntry_;
1053  V.fname  = NULL;  /* don't know */
1054  V.seq    = (char*) calloc(1, kStartLength+1);
1055  V.maxseq = kStartLength;
1056  V.seqlen = 0;
1057  V.seqid  = seqid_;
1058
1059  V.f = fp_;
1060  V.filestart= (ftell( fp_) == 0);
1061  /* !! in sequential read, must remove current seq position from choice/whichEntry_ counter !! ... */
1062  if (V.filestart)  V.nseq = 0;
1063  else V.nseq= *nseq_;  /* track where we are in file...*/
1064
1065  *V.seqid = '\0';
1066  V.err = 0;
1067  V.nseq = 0;
1068  V.isseqchar = isSeqChar;
1069  V.isseqcharfirst8 = 0;
1070  if (V.choice == kListSequences) ; /* leave as is */
1071  else if (V.choice <= 0) V.choice = 1; /* default ?? */
1072  V.addit = (V.choice > 0);
1073  V.allDone = false;
1074
1075  readSeqMain(&V, skiplines_, format_);
1076
1077  *error_ = V.err;
1078  *seqlen_ = V.seqlen;
1079  *nseq_ = V.nseq;
1080  return V.seq;
1081}
1082
1083char *readSeq(
1084      const short whichEntry_,  /* index to sequence in file */
1085      const char  *filename_,   /* file name */
1086      const long  skiplines_,
1087      const short format_,      /* sequence file format */
1088      long  *seqlen_,     /* return seq size */
1089      short *nseq_,       /* number of seqs in file, for listSeqs() */
1090      short *error_,      /* return error */
1091      char  *seqid_)      /* return seq name/info */
1092{
1093  struct ReadSeqVars V;
1094
1095  if (format_ < kMinFormat || format_ > kMaxFormat) {
1096    *error_ = eUnknownFormat;
1097    *seqlen_ = 0;
1098    return NULL;
1099    }
1100
1101  V.choice = whichEntry_;
1102  V.fname  = filename_;  /* don't need to copy string, just ptr to it */
1103  V.seq    = (char*) calloc(1, kStartLength+1);
1104  V.maxseq = kStartLength;
1105  V.seqlen = 0;
1106  V.seqid  = seqid_;
1107
1108  V.f = NULL;
1109  *V.seqid = '\0';
1110  V.err = 0;
1111  V.nseq = 0;
1112  V.isseqchar = isSeqChar;
1113  V.isseqcharfirst8 = 0;
1114  if (V.choice == kListSequences) ; /* leave as is */
1115  else if (V.choice <= 0) V.choice = 1; /* default ?? */
1116  V.addit = (V.choice > 0);
1117  V.allDone = false;
1118
1119  V.f = fopen(V.fname, "r");
1120  V.filestart= true;
1121
1122  readSeqMain(&V, skiplines_, format_);
1123
1124  if (V.f != NULL) fclose(V.f);
1125  *error_ = V.err;
1126  *seqlen_ = V.seqlen;
1127  *nseq_ = V.nseq;
1128  return V.seq;
1129}
1130
1131
1132
1133
1134
1135char *listSeqs(
1136      const char  *filename_,   /* file name */
1137      const long skiplines_,
1138      const short format_,      /* sequence file format */
1139      short *nseq_,       /* number of seqs in file, for listSeqs() */
1140      short *error_)      /* return error */
1141{
1142  char  seqid[256];
1143  long  seqlen;
1144
1145  return readSeq( kListSequences, filename_, skiplines_, format_,
1146                  &seqlen, nseq_, error_, seqid);
1147}
1148
1149
1150
1151
1152short seqFileFormat(    /* return sequence format number, see ureadseq.h */
1153    const char *filename,
1154    long  *skiplines,   /* return #lines to skip any junk like mail header */
1155    short *error)       /* return any error value or 0 */
1156{
1157  FILE      *fseq;
1158  short      format;
1159
1160  fseq  = fopen(filename, "r");
1161  format= seqFileFormatFp( fseq, skiplines, error);
1162  if (fseq!=NULL) fclose(fseq);
1163  return format;
1164}
1165
1166short seqFileFormatFp(
1167    FILE *fseq,
1168    long  *skiplines,   /* return #lines to skip any junk like mail header */
1169    short *error)       /* return any error value or 0 */
1170{
1171  boolean   foundIG= false, foundStrider= false,
1172            foundGB= false, foundPIR= false, foundEMBL= false, foundNBRF= false,
1173            foundPearson= false, foundFitch= false, foundPhylip= false, foundZuker= false,
1174            gotolsen= false, gotpaup = false, gotasn1 = false, gotuw= false, gotMSF= false,
1175            isfitch= false,  isphylip= false, done= false;
1176  short     format= kUnknown;
1177  int       nlines= 0, k, splen= 0, otherlines= 0, aminolines= 0, dnalines= 0;
1178  char      sp[256];
1179  long      linestart=0;
1180  int     maxlines2check=500;
1181
1182#define ReadOneLine(sp)   \
1183  { done |= (feof(fseq)); \
1184    readline( fseq, sp, &linestart);  \
1185    if (!done) { splen = strlen(sp); ++nlines; } }
1186
1187  *skiplines = 0;
1188  *error = 0;
1189  if (fseq == NULL) { *error = eFileNotFound;  return kNoformat; }
1190
1191  while ( !done ) {
1192    ReadOneLine(sp);
1193
1194    /* check for mailer head & skip past if found */
1195    if (nlines < 4 && !done) {
1196      if ((strstr(sp,"From ") == sp) || (strstr(sp,"Received:") == sp)) {
1197        do {
1198          /* skip all lines until find one blank line */
1199          ReadOneLine(sp);
1200          if (!done) for (k=0; (k<splen) && (sp[k]==' '); k++) ;
1201          } while ((!done) && (k < splen));
1202        *skiplines = nlines; /* !? do we want #lines or #bytes ?? */
1203        }
1204      }
1205
1206    if (sp==NULL || *sp==0)
1207      ; /* nada */
1208
1209    /* high probability identities: */
1210
1211    else if ( strstr(sp,"MSF:") && strstr(sp,"Type:") && strstr(sp,"Check:") )
1212      gotMSF= true;
1213
1214    else if ((strstr(sp,"..") != NULL) && (strstr(sp,"Check:") != NULL))
1215      gotuw= true;
1216
1217    else if (strstr(sp,"identity:   Data:") != NULL)
1218      gotolsen= true;
1219
1220    else if ( strstr(sp,"::=") &&
1221      (strstr(sp,"Bioseq") ||       /* Bioseq or Bioseq-set */
1222       strstr(sp,"Seq-entry") ||
1223       strstr(sp,"Seq-submit") ) )  /* can we read submit format? */
1224          gotasn1= true;
1225
1226    else if ( strstr(sp,"#NEXUS") == sp )
1227      gotpaup= true;
1228
1229    /* uncertain identities: */
1230
1231    else if (*sp ==';') {
1232      if (strstr(sp,"Strider") !=NULL) foundStrider= true;
1233      else foundIG= true;
1234      }
1235
1236    else if (strstr(sp,"LOCUS") == sp)
1237      foundGB= true;
1238    else if (strstr(sp,"ORIGIN") == sp)
1239      foundGB= true;
1240
1241    else if (strstr(sp,"ENTRY   ") == sp)  /* ? also (strcmp(sp,"\\\\\\")==0) */
1242      foundPIR= true;
1243    else if (strstr(sp,"SEQUENCE") == sp)
1244      foundPIR= true;
1245
1246    else if (*sp == '>') {
1247      if (sp[3] == ';') foundNBRF= true;
1248      else foundPearson= true;
1249      }
1250
1251    else if (strstr(sp,"ID   ") == sp)
1252      foundEMBL= true;
1253    else if (strstr(sp,"SQ   ") == sp)
1254      foundEMBL= true;
1255
1256    else if (*sp == '(')
1257      foundZuker= true;
1258
1259    else {
1260      if (nlines - *skiplines == 1) {
1261        int ispp= 0, ilen= 0;
1262        sscanf( sp, "%d%d", &ispp, &ilen);
1263        if (ispp > 0 && ilen > 0) isphylip= true;
1264        }
1265      else if (isphylip && nlines - *skiplines == 2) {
1266        int  tseq;
1267        tseq= getseqtype(sp+10, strlen(sp+10));
1268        if ( isalpha(*sp)     /* 1st letter in 2nd line must be of a name */
1269         && (tseq != kOtherSeq))  /* sequence section must be okay */
1270            foundPhylip= true;
1271        }
1272
1273      for (k=0, isfitch= true; isfitch & (k < splen); k++) {
1274        if (k % 4 == 0) isfitch &= (sp[k] == ' ');
1275        else isfitch &= (sp[k] != ' ');
1276        }
1277      if (isfitch & (splen > 20)) foundFitch= true;
1278
1279      /* kRNA && kDNA are fairly certain...*/
1280      switch (getseqtype( sp, splen)) {
1281        case kOtherSeq: otherlines++; break;
1282        case kAmino   : if (splen>20) aminolines++; break;
1283        case kDNA     :
1284        case kRNA     : if (splen>20) dnalines++; break;
1285        case kNucleic : break; /* not much info ? */
1286        }
1287
1288      }
1289
1290                    /* pretty certain */
1291    if (gotolsen) {
1292      format= kOlsen;
1293      done= true;
1294      }
1295    else if (gotMSF) {
1296      format= kMSF;
1297      done= true;
1298      }
1299    else if (gotasn1) {
1300      /* !! we need to look further and return  kASNseqentry | kASNseqset */
1301      /*
1302        seqentry key is Seq-entry ::=
1303        seqset key is Bioseq-set ::=
1304        ?? can't read these yet w/ ncbi tools ??
1305          Seq-submit ::=
1306          Bioseq ::=  << fails both bioseq-seq and seq-entry parsers !
1307      */
1308      if (strstr(sp,"Bioseq-set")) format= kASNseqset;
1309      else if (strstr(sp,"Seq-entry")) format= kASNseqentry;
1310      else format= kASN1;  /* other form, we can't yet read... */
1311      done= true;
1312      }
1313    else if (gotpaup) {
1314      format= kPAUP;
1315      done= true;
1316      }
1317
1318    else if (gotuw) {
1319      if (foundIG) format= kIG;  /* a TOIG file from GCG for certain */
1320      else format= kGCG;
1321      done= true;
1322      }
1323
1324    else if ((dnalines > 1) || done || (nlines > maxlines2check)) {
1325          /* decide on most likely format */
1326          /* multichar idents: */
1327      if (foundStrider) format= kStrider;
1328      else if (foundGB) format= kGenBank;
1329      else if (foundPIR) format= kPIR;
1330      else if (foundEMBL) format= kEMBL;
1331      else if (foundNBRF) format= kNBRF;
1332          /* single char idents: */
1333      else if (foundIG) format= kIG;
1334      else if (foundPearson) format= kPearson;
1335      else if (foundZuker) format= kZuker;
1336          /* digit ident: */
1337      else if (foundPhylip) format= kPhylip;
1338          /* spacing ident: */
1339      else if (foundFitch) format= kFitch;
1340          /* no format chars: */
1341      else if (otherlines > 0) format= kUnknown;
1342      else if (dnalines > 1) format= kPlain;
1343      else if (aminolines > 1) format= kPlain;
1344      else format= kUnknown;
1345
1346      done= true;
1347      }
1348
1349    /* need this for possible long header in olsen format */
1350     else if (strstr(sp,"): ") != NULL)
1351       maxlines2check++;
1352    }
1353
1354  if (format == kPhylip) {
1355    /* check for interleaved or sequential -- really messy */
1356    int tname, tseq;
1357    long i, j, nspp= 0, nlen= 0, ilen, leaf= 0, seq= 0;
1358    char  *ps;
1359
1360    rewind(fseq);
1361    for (i=0; i < *skiplines; i++) ReadOneLine(sp);
1362    nlines= 0;
1363    ReadOneLine(sp);
1364    sscanf( sp, "%ld%ld", &nspp, &nlen);
1365    ReadOneLine(sp); /* 1st seq line */
1366    for (ps= sp+10, ilen=0; *ps!=0; ps++) if (isprint(*ps)) ilen++;
1367
1368    for (i= 1; i<nspp; i++) {
1369      ReadOneLine(sp);
1370
1371      tseq= getseqtype(sp+10, strlen(sp+10));
1372      tname= getseqtype(sp, 10);
1373      for (j=0, ps= sp; isspace(*ps) && j<10; ps++, j++);
1374      for (ps= sp; *ps!=0; ps++) if (isprint(*ps)) ilen++;
1375
1376      /* find probable interleaf or sequential ... */
1377      if (j>=9) seq += 10; /* pretty certain not ileaf */
1378      else {
1379        if (tseq != tname) leaf++; else seq++;
1380        if (tname == kDNA || tname == kRNA) seq++; else leaf++;
1381        }
1382
1383      if (ilen <= nlen && j<9) {
1384        if (tname == kOtherSeq) leaf += 10;
1385        else if (tname == kAmino || tname == kDNA || tname == kRNA) seq++; else leaf++;
1386        }
1387      else if (ilen > nlen) {
1388        ilen= 0;
1389        }
1390      }
1391    for ( nspp *= 2 ; i<nspp; i++) {  /* this should be only bases if interleaf */
1392      ReadOneLine(sp);
1393
1394      tseq= getseqtype(sp+10, strlen(sp+10));
1395      tname= getseqtype(sp, 10);
1396      for (ps= sp; *ps!=0; ps++) if (isprint(*ps)) ilen++;
1397      for (j=0, ps= sp; isspace(*ps) && j<10; ps++, j++);
1398      if (j<9) {
1399        if (tname == kOtherSeq) seq += 10;
1400        if (tseq != tname) seq++; else leaf++;
1401        if (tname == kDNA || tname == kRNA) leaf++; else seq++;
1402        }
1403      if (ilen > nlen) {
1404        if (j>9) leaf += 10; /* must be a name here for sequent */
1405        else if (tname == kOtherSeq) seq += 10;
1406        ilen= 0;
1407        }
1408      }
1409
1410    if (leaf > seq) format= kPhylip4;
1411    else format= kPhylip2;
1412    }
1413
1414  return(format);
1415#undef  ReadOneLine
1416} /* SeqFileFormat */
1417
1418
1419
1420
1421unsigned long GCGchecksum( const char *seq, const long seqlen, unsigned long *checktotal)
1422/* GCGchecksum */
1423{
1424    long  i, check = 0, count = 0;
1425
1426  for (i = 0; i < seqlen; i++) {
1427    count++;
1428    check += count * to_upper(seq[i]);
1429    if (count == 57) count = 0;
1430    }
1431  check %= 10000;
1432  *checktotal += check;
1433  *checktotal %= 10000;
1434  return check;
1435}
1436
1437/* Table of CRC-32's of all single byte values (made by makecrc.c of ZIP source) */
1438const unsigned long crctab[] = {
1439  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
1440  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
1441  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
1442  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
1443  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
1444  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
1445  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
1446  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
1447  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
1448  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
1449  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
1450  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
1451  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
1452  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
1453  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
1454  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
1455  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
1456  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
1457  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
1458  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
1459  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
1460  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
1461  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
1462  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
1463  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
1464  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
1465  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
1466  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
1467  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
1468  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
1469  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
1470  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
1471  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
1472  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
1473  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
1474  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
1475  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
1476  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
1477  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
1478  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
1479  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
1480  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
1481  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
1482  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
1483  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
1484  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
1485  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
1486  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
1487  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
1488  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
1489  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
1490  0x2d02ef8dL
1491};
1492
1493unsigned long CRC32checksum(const char *seq, const long seqlen, unsigned long *checktotal)
1494/*CRC32checksum: modified from CRC-32 algorithm found in ZIP compression source */
1495{
1496  unsigned long c = 0xffffffffL;
1497  long n = seqlen;
1498
1499  if (!seq) return 0;
1500  while (n--) {
1501      c = crctab[((int)c ^ (to_upper(*seq))) & 0xff] ^ (c >> 8);
1502      seq++; /* fixed aug'98 finally */
1503  }
1504  c= c ^ 0xffffffffL;
1505  *checktotal += c;
1506  return c;
1507}
1508
1509
1510
1511
1512short getseqtype( const char *seq, const long seqlen)
1513{ /* return sequence kind: kDNA, kRNA, kProtein, kOtherSeq, ??? */
1514  char  c;
1515  short i, maxtest;
1516  short na = 0, aa = 0, po = 0, nt = 0, nu = 0, ns = 0, no = 0;
1517
1518  maxtest = min(300, seqlen);
1519  for (i = 0; i < maxtest; i++) {
1520    c = to_upper(seq[i]);
1521    if (strchr(protonly, c)) po++;
1522    else if (strchr(primenuc,c)) {
1523      na++;
1524      if (c == 'T') nt++;
1525      else if (c == 'U') nu++;
1526      }
1527    else if (strchr(aminos,c)) aa++;
1528    else if (strchr(seqsymbols,c)) ns++;
1529    else if (isalpha(c)) no++;
1530    }
1531
1532  if ((no > 0) || (po+aa+na == 0)) return kOtherSeq;
1533  /* ?? test for probability of kOtherSeq ?, e.g.,
1534  else if (po+aa+na / maxtest < 0.70) return kOtherSeq;
1535  */
1536  else if (po > 0) return kAmino;
1537  else if (aa == 0) {
1538    if (nu > nt) return kRNA;
1539    else return kDNA;
1540    }
1541  else if (na > aa) return kNucleic;
1542  else return kAmino;
1543} /* getseqtype */
1544
1545
1546char* compressSeq( const char gapc, const char *seq, const long seqlen, long *newlen)
1547{
1548  char *a, *b;
1549  long i;
1550  char  *newseq;
1551
1552  *newlen= 0;
1553  if (!seq) return NULL;
1554  newseq = (char*) malloc(seqlen+1);
1555  if (!newseq) return NULL;
1556  for (a= (char*)seq, b=newseq, i=0; *a!=0; a++)
1557    if (*a != gapc) {
1558      *b++= *a;
1559      i++;
1560      }
1561  *b= '\0';
1562  newseq = (char*) realloc(newseq, i+1);
1563  *newlen= i;
1564  return newseq;
1565}
1566
1567
1568
1569/***
1570char *rtfhead = "{\\rtf1\\defformat\\mac\\deff2 \
1571{\\fonttbl\
1572  {\\f1\\fmodern Courier;}{\\f2\\fmodern Monaco;}\
1573  {\\f3\\fswiss Helvetica;}{\\f4\\fswiss Geneva;}\
1574  {\\f5\\froman Times;}{\\f6\\froman Palatino;}\
1575  {\\f7\\froman New Century Schlbk;}{\\f8\\ftech Symbol;}}\
1576{\\stylesheet\
1577  {\\s1 \\f5\\fs20 \\sbasedon0\\snext1 name;}\
1578  {\\s2 \\f3\\fs20 \\sbasedon0\\snext2 num;}\
1579  {\\s3 \\f1\\f21 \\sbasedon0\\snext3 seq;}}";
1580
1581char *rtftail = "}";
1582****/
1583
1584short writeSeq(FILE *outf, const char *seq, const long seqlen,
1585                const short outform, const char *seqid)
1586/* dump sequence to standard output */
1587{
1588  const short kSpaceAll = -9;
1589#define kMaxseqwidth  250
1590
1591  boolean baseonlynum= false; /* nocountsymbols -- only count true bases, not "-" */
1592  short  numline = 0; /* only true if we are writing seq number line (for interleave) */
1593  boolean numright = false, numleft = false;
1594  boolean nameright = false, nameleft = false;
1595  short   namewidth = 8, numwidth = 8;
1596  short   spacer = 0, width  = 50, tab = 0;
1597  /* new parameters: width, spacer, those above... */
1598
1599  short linesout = 0, seqtype = kNucleic;
1600  long  i, j, l, l1, ibase;
1601  char  idword[31], endstr[10];
1602  char  seqnamestore[128], *seqname = seqnamestore;
1603  char  s[kMaxseqwidth], *cp;
1604  char  nameform[10], numform[10], nocountsymbols[10];
1605  unsigned long checksum = 0, checktotal = 0;
1606
1607  gPretty.atseq++;
1608  skipwhitespace(seqid);
1609  l = min(128, strlen(seqid));
1610  strncpy( seqnamestore, seqid, l);
1611  seqname[l] = 0;
1612
1613  sscanf( seqname, "%30s", idword);
1614  sprintf(numform, "%ld", seqlen);
1615  numwidth= strlen(numform)+1;
1616  nameform[0]= '\0';
1617
1618  if (strstr(seqname,"checksum") != NULL) {
1619    cp = strstr(seqname,"bases");
1620    if (cp!=NULL) {
1621      for ( ; (cp!=seqname) && (*cp!=','); cp--) ;
1622      if (cp!=seqname) *cp=0;
1623      }
1624    }
1625
1626  strcpy( endstr,"");
1627  l1 = 0;
1628
1629  if (outform == kGCG || outform == kMSF)
1630    checksum = GCGchecksum(seq, seqlen, &checktotal);
1631  else
1632    checksum = seqchecksum(seq, seqlen, &checktotal);
1633
1634  switch (outform) {
1635
1636    case kPlain:
1637    case kUnknown:    /* no header, just sequence */
1638      strcpy(endstr,"\n"); /* end w/ extra blank line */
1639      break;
1640
1641    case kOlsen:  /* Olsen seq. editor takes plain nucs OR Genbank  */
1642    case kGenBank:
1643      fprintf(outf,"LOCUS       %s       %ld bp\n", idword, seqlen);
1644      fprintf(outf,"DEFINITION  %s, %ld bases, %lX checksum.\n", seqname, seqlen, checksum);
1645   /* fprintf(outf,"ACCESSION   %s\n", accnum); */
1646      fprintf(outf,"ORIGIN      \n");
1647      spacer = 11;
1648      numleft = true;
1649      numwidth = 8;  /* dgg. 1Feb93, patch for GDE fail to read short numwidth */
1650      strcpy(endstr, "\n//");
1651      linesout += 4;
1652      break;
1653
1654    case kPIR:
1655      /* somewhat like genbank... \\\*/
1656      /* fprintf(outf,"\\\\\\\n"); << only at top of file, not each entry... */
1657      fprintf(outf,"ENTRY           %s \n", idword);
1658      fprintf(outf,"TITLE           %s, %ld bases, %lX checksum.\n", seqname, seqlen, checksum);
1659   /* fprintf(outf,"ACCESSION       %s\n", accnum); */
1660      fprintf(outf,"SEQUENCE        \n");
1661      numwidth = 7;
1662      width= 30;
1663      spacer = kSpaceAll;
1664      numleft = true;
1665      strcpy(endstr, "\n///");
1666      /* run a top number line for PIR */
1667      for (j=0; j<numwidth; j++) fputc(' ',outf);
1668      for (j= 5; j<=width; j += 5) fprintf(outf,"%10ld",j);
1669      fputc('\n',outf);
1670      linesout += 5;
1671      break;
1672
1673    case kNBRF:
1674      if (getseqtype(seq, seqlen) == kAmino)
1675        fprintf(outf,">P1;%s\n", idword);
1676      else
1677        fprintf(outf,">DL;%s\n", idword);
1678      fprintf(outf,"%s, %ld bases, %lX checksum.\n", seqname, seqlen, checksum);
1679      spacer = 11;
1680      strcpy(endstr,"*\n");
1681      linesout += 3;
1682      break;
1683
1684    case kEMBL:
1685      fprintf(outf,"ID   %s\n", idword);
1686  /*  fprintf(outf,"AC   %s\n", accnum); */
1687      fprintf(outf,"DE   %s, %ld bases, %lX checksum.\n", seqname, seqlen, checksum);
1688      fprintf(outf,"SQ             %ld BP\n", seqlen);
1689      strcpy(endstr, "\n//"); /* 11Oct90: bug fix*/
1690      tab = 4;     /** added 31jan91 */
1691      spacer = 11; /** added 31jan91 */
1692      width = 60;
1693      linesout += 4;
1694      break;
1695
1696    case kGCG:
1697      fprintf(outf,"%s\n", seqname);
1698   /* fprintf(outf,"ACCESSION   %s\n", accnum); */
1699      fprintf(outf,"    %s  Length: %ld  (today)  Check: %ld  ..\n", idword, seqlen, checksum);
1700      spacer = 11;
1701      numleft = true;
1702      strcpy(endstr, "\n");  /* this is insurance to help prevent misreads at eof */
1703      linesout += 3;
1704      break;
1705
1706    case kStrider: /* ?? map ?*/
1707      fprintf(outf,"; ### from DNA Strider ;-)\n");
1708      fprintf(outf,"; DNA sequence  %s, %ld bases, %lX checksum.\n;\n", seqname, seqlen, checksum);
1709      strcpy(endstr, "\n//");
1710      linesout += 3;
1711      break;
1712
1713    case kFitch:
1714      fprintf(outf,"%s, %ld bases, %lX checksum.\n", seqname, seqlen, checksum);
1715      spacer = 4;
1716      width = 60;
1717      linesout += 1;
1718      break;
1719
1720    case kPhylip2:
1721    case kPhylip4:
1722      /* this is version 3.2/3.4 -- simplest way to write
1723        version 3.3 is to write as version 3.2, then
1724        re-read file and interleave the species lines */
1725      if (strlen(idword)>10) idword[10] = 0;
1726      fprintf(outf,"%-10s  ",idword);
1727      l1  = -1;
1728      tab = 12;
1729      spacer = 11;
1730      break;
1731
1732    case kASN1:
1733      seqtype= getseqtype(seq, seqlen);
1734      switch (seqtype) {
1735        case kDNA     : cp= (char*)"dna"; break;
1736        case kRNA     : cp= (char*)"rna"; break;
1737        case kNucleic : cp= (char*)"na"; break;
1738        case kAmino   : cp= (char*)"aa"; break;
1739        case kOtherSeq: cp= (char*)"not-set"; break;
1740        }
1741      fprintf(outf,"  seq {\n");
1742      fprintf(outf,"    id { local id %d },\n", gPretty.atseq);
1743      fprintf(outf,"    descr { title \"%s\" },\n", seqid);
1744      fprintf(outf,"    inst {\n");
1745      fprintf(outf,"      repr raw, mol %s, length %ld, topology linear,\n", cp, seqlen);
1746      fprintf(outf,"      seq-data\n");
1747      if (seqtype == kAmino)
1748        fprintf(outf,"        iupacaa \"");
1749      else
1750        fprintf(outf,"        iupacna \"");
1751      l1  = 17;
1752      spacer = 0;
1753      width  = 78;
1754      tab  = 0;
1755      strcpy(endstr,"\"\n      } } ,");
1756      linesout += 7;
1757      break;
1758
1759    case kPAUP:
1760      nameleft= true;
1761      namewidth = 9;
1762      spacer = 21;
1763      width  = 100;
1764      tab  = 0; /* 1; */
1765      /* strcpy(endstr,";\nend;"); << this is end of all seqs.. */
1766      /* do a header comment line for paup */
1767      fprintf(outf,"[Name: %-16s  Len:%6ld  Check: %8lX]\n", idword, seqlen, checksum);
1768      linesout += 1;
1769      break;
1770
1771    case kPretty:
1772      numline= gPretty.numline;
1773      baseonlynum= gPretty.baseonlynum;
1774      namewidth = gPretty.namewidth;
1775      numright = gPretty.numright;
1776      numleft = gPretty.numleft;
1777      nameright = gPretty.nameright;
1778      nameleft = gPretty.nameleft;
1779      spacer = gPretty.spacer + 1;
1780      width  = gPretty.seqwidth;
1781      tab  = gPretty.tab;
1782      /* also add rtf formatting w/ font, size, style */
1783      if (gPretty.nametop) {
1784        fprintf(outf,"Name: %-16s  Len:%6ld  Check: %8lX\n", idword, seqlen, checksum);
1785        linesout++;
1786        }
1787      break;
1788
1789    case kMSF:
1790      fprintf(outf," Name: %-16s Len:%6ld  Check: %5ld  Weight:  1.00\n",
1791                    idword, seqlen, checksum);
1792      linesout++;
1793      nameleft= true;
1794      namewidth= 15; /* need MAX namewidth here... */
1795      sprintf(nameform, "%%+%ds ",namewidth);
1796      spacer = 11;
1797      width  = 50;
1798      tab = 0; /* 1; */
1799      break;
1800
1801    case kIG:
1802      fprintf(outf,";%s, %ld bases, %lX checksum.\n", seqname, seqlen, checksum);
1803      fprintf(outf,"%s\n", idword);
1804      strcpy(endstr,"1"); /* == linear dna */
1805      linesout += 2;
1806      break;
1807
1808    default :
1809    case kZuker: /* don't attempt Zuker's ftn format */
1810    case kPearson:
1811      fprintf(outf,">%s, %ld bases, %lX checksum.\n", seqname, seqlen, checksum);
1812      linesout += 1;
1813      break;
1814    }
1815
1816  if (*nameform==0) sprintf(nameform, "%%%d.%ds ",namewidth,namewidth);
1817  if (numline) sprintf(numform, "%%%ds ",numwidth);
1818  else sprintf(numform, "%%%dd ",numwidth);
1819  strcpy( nocountsymbols, kNocountsymbols);
1820  if (baseonlynum) {
1821    if (strchr(nocountsymbols,gPretty.gapchar)==NULL) {
1822      strcat(nocountsymbols," ");
1823      nocountsymbols[strlen(nocountsymbols)-1]= gPretty.gapchar;
1824      }
1825    if (gPretty.domatch && (cp=strchr(nocountsymbols,gPretty.matchchar))!=NULL) {
1826      *cp= ' ';
1827      }
1828    }
1829
1830  if (numline) {
1831   *idword= 0;
1832   }
1833
1834  width = min(width,kMaxseqwidth);
1835  for (i=0, l=0, ibase = 1; i < seqlen; ) {
1836
1837    if (l1 < 0) l1 = 0;
1838    else if (l1 == 0) {
1839      if (nameleft) fprintf(outf, nameform, idword);
1840      if (numleft) { if (numline) fprintf(outf, numform, "");
1841                    else fprintf(outf, numform, ibase);}
1842      for (j=0; j<tab; j++) fputc(' ',outf);
1843      }
1844
1845    l1++;                 /* don't count spaces for width*/
1846    if (numline) {
1847      if (spacer==kSpaceAll || (spacer != 0 && (l+1) % spacer == 1)) {
1848        if (numline==1) fputc(' ',outf);
1849        s[l++] = ' ';
1850        }
1851      if (l1 % 10 == 1 || l1 == width) {
1852        if (numline==1) fprintf(outf,"%-9ld ",i+1);
1853        s[l++]= '|'; /* == put a number here */
1854        }
1855      else s[l++]= ' ';
1856      i++;
1857      }
1858
1859    else {
1860      if (spacer==kSpaceAll || (spacer != 0 && (l+1) % spacer == 1))
1861        s[l++] = ' ';
1862      if (!baseonlynum) ibase++;
1863      else if (0==strchr(nocountsymbols,seq[i])) ibase++;
1864      s[l++] = seq[i++];
1865      }
1866
1867    if (l1 == width || i == seqlen) {
1868      if (outform==kPretty) for ( ; l1<width; l1++) {
1869        if (spacer==kSpaceAll || (spacer != 0 && (l+1) % spacer == 1))
1870          s[l++] = ' ';
1871        s[l++]=' '; /* pad w/ blanks */
1872        }
1873      s[l] = '\0';
1874      l = 0; l1 = 0;
1875
1876      if (numline) {
1877        if (numline==2) fprintf(outf,"%s",s); /* finish numberline ! and | */
1878        }
1879      else {
1880        if (i == seqlen) fprintf(outf,"%s%s",s,endstr);
1881        else fprintf(outf,"%s",s);
1882        if (numright || nameright) fputc(' ',outf);
1883        if (numright)  fprintf(outf,numform, ibase-1);
1884        if (nameright) fprintf(outf, nameform,idword);
1885        }
1886      fputc('\n',outf);
1887      linesout++;
1888      }
1889    }
1890  return linesout;
1891}  /*writeSeq*/
1892
1893
1894
1895/* End file: ureadseq.c */
Note: See TracBrowser for help on using the repository browser.