source: tags/initial/READSEQ/ureadseq.c

Last change on this file was 2, checked in by oldcode, 25 years ago

Initial revision

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