JPRED-2 Add sources of all binaries (except alscript) to Git
[jpred.git] / sources / seg / genwin.c
1
2 /*****************************************************************************/
3 /***   (genwin.c)                                                          ***/
4 /*****************************************************************************/
5
6 /*--------------------------------------------------------------(includes)---*/
7
8 #include "genwin.h"
9
10 /*---------------------------------------------------------------(defines)---*/
11
12 #define STRSIZE 100
13
14 /*----------------------------------------------------------------(protos)---*/
15
16 struct Sequence *readentry();
17
18 /*---------------------------------------------------------------(globals)---*/
19
20 char *blastdbs[] =
21   {"bba", "bbn", "embl", "gbupdate", "genbank", "genpept", "gpupdate",
22    "nr", "nrdb", "nrdb.shuf", "pir", "pseq", "swissprot", "tfdaa"};
23
24 int nblastdbs = 14;
25
26 #ifndef MIN
27 #define MIN(a,b) ((a) <= (b) ? (a) : (b))
28 #endif
29
30 char *blastdir = "/net/cruncher/usr/ncbi/db/fasta/";
31 char *indexdir = "/net/cruncher/usr/ncbi/db/index/";
32
33 int nabets;
34 struct Alphabet **abets;
35 int ntvecs;
36 struct TransVector **tvecs;
37 int nsvecs;
38 struct ScoreVector **svecs;
39 int nsmats;
40 struct ScoreMatrix **smats;
41
42 int aaindex[128];
43 unsigned char   aaflag[128];
44 char aachar[20];
45
46 struct strlist
47   {
48    char string[STRSIZE];
49    struct strlist *next;
50   } *str, *curstr;
51
52 /*---------------------------------------------------------------(tmalloc)---*/
53
54 #define TESTMAX 1000
55 void *tmalloc();
56 int record_ptrs[TESTMAX] = {0,0,0,0};
57 int rptr = 0;
58
59 /*------------------------------------------------------------(genwininit)---*/
60
61 genwininit()
62 {
63         char    *cp, *cp0;
64         int             i;
65         char    c;
66
67         for (i = 0; i < sizeof(aaindex)/sizeof(aaindex[0]); ++i) {
68                 aaindex[i] = 20;
69                 aaflag[i] = TRUE;
70         }
71                 
72         for (cp = cp0 = "ACDEFGHIKLMNPQRSTVWY"; (c = *cp) != '\0'; ++cp) {
73                 i = cp - cp0;
74                 aaindex[c] = i;
75                 aaindex[tolower(c)] = i;
76                 aachar[i] = tolower(c);
77                 aaflag[c] = FALSE;
78                 aaflag[tolower(c)] = FALSE;
79         }
80         return;
81 }
82         
83 /*-------------------------------------------------------------(opendbase)---*/
84
85 extern struct Database *opendbase(name)
86   char *name;
87
88   {struct Database *dbase;
89
90    dbase = (struct Database *) malloc(sizeof(struct Database));
91
92    if (blastdb(name))
93      {
94       dbase->filename = (char *) malloc(strlen(blastdir)+strlen(name)+1);
95       dbase->indexname = (char *) malloc(strlen(indexdir)+strlen(name)+1);
96       strcpy(dbase->filename, blastdir);
97       strcat(dbase->filename, name);
98       strcpy(dbase->indexname, indexdir);
99       strcat(dbase->indexname, name);
100      }
101    else
102      {
103       dbase->filename = (char *) malloc(strlen(name)+1);
104       dbase->indexname = (char *) malloc(strlen(name)+1);
105       strcpy(dbase->filename, name);
106       strcpy(dbase->indexname, name);
107      }
108
109    if (strcmp(dbase->filename, "-")==0)
110      {
111       dbase->fp = stdin;
112      }
113    else if ((dbase->fp=fopen(dbase->filename, "r"))==NULL)
114      {
115       free(dbase->filename);
116       free(dbase->indexname);
117       free(dbase);
118       return((struct Database *) NULL);
119      }
120
121    dbase->filepos = 0L;
122
123    return(dbase);
124   }
125
126 /*---------------------------------------------------------------(blastdb)---*/
127
128 int blastdb(name)
129   char *name;
130
131   {int i;
132
133    for (i=0; i<nblastdbs; i++)
134      {
135       if (strcmp(name, blastdbs[i])==0) {return(TRUE);}
136      }
137
138    return(FALSE);
139   }
140
141 /*------------------------------------------------------------(closedbase)---*/
142
143 extern closedbase(dbase)
144   struct Database *dbase;
145
146   {
147    fclose(dbase->fp);
148    free(dbase->filename);
149    free(dbase->indexname);
150    free(dbase);
151
152    return;
153   }
154
155 /*--------------------------------------------------------------(firstseq)---*/
156
157 extern struct Sequence *firstseq(dbase)
158   struct Database *dbase;
159
160   {
161    if (dbase->filepos!=0L)
162      {
163       dbase->filepos = 0L;
164       if (fseek(dbase->fp, dbase->filepos, 0)!=0)
165         {fprintf(stderr, "Error positioning file %s for firstseq.\n",
166                            dbase->filename);
167          exit(1);}
168      }
169
170    return(readentry(dbase));
171   }
172
173 /*---------------------------------------------------------------(nextseq)---*/
174
175 extern struct Sequence *nextseq(dbase)
176   struct Database *dbase;
177
178   {
179    return(readentry(dbase));
180   }
181
182 /*--------------------------------------------------------------(closeseq)---*/
183
184 extern closeseq(seq)
185   struct Sequence *seq;
186
187   {
188    if (seq==NULL) return;
189
190    if (seq->id!=NULL)          free(seq->id);
191    if (seq->name!=NULL)        free(seq->name);
192    if (seq->organism!=NULL)    free(seq->organism);
193    if (seq->header!=NULL)      free(seq->header);
194    if (seq->state!=NULL)       free(seq->state);
195    if (seq->composition!=NULL) free(seq->composition);
196    free(seq->seq);
197    free(seq);
198    return;
199   }
200
201 /*---------------------------------------------------------------(openwin)---*/
202
203 extern struct Sequence *openwin(parent, start, length)
204   struct Sequence *parent;
205   int start, length;
206
207   {struct Sequence *win;
208    int i;
209
210    if (start<0 || length<0 || start+length>parent->length)
211      {
212       return((struct Sequence *) NULL);
213      }
214
215    win = (struct Sequence *) malloc(sizeof(struct Sequence));
216
217 /*---                                          ---[set links, up and down]---*/
218
219    win->parent = parent;
220    if (parent->root==NULL)
221      {win->root = parent;}
222    else
223      {win->root = parent->root;}
224    win->children = (struct Sequence **) NULL;
225
226 /* parent->children = ***foo***                   ---[not yet implemented]---*/
227
228    win->id = (char *) NULL;
229    win->name = (char *) NULL;
230    win->organism = (char *) NULL;
231    win->header = (char *) NULL;
232
233 /*---                          ---[install the local copy of the sequence]---*/
234
235    win->start = start;
236    win->length = length;
237 #if 0
238    win->seq = (char *) malloc(sizeof(char)*length + 1);
239    memcpy(win->seq, (parent->seq)+start, length);
240    win->seq[length] = '\0';
241 #else
242         win->seq = parent->seq + start;
243 #endif
244
245 /*---                          ---[setup window implementation parameters]---*/
246
247 /*---                                                 ---[set local flags]---*/
248
249         win->rubberwin = FALSE;
250         win->floatwin = FALSE;
251         win->punctuation = FALSE;
252
253 /*---                                   ---[initially unconfiguerd window]---*/
254
255         win->entropy = -2.;
256         win->state = (int *) NULL;
257         win->composition = (int *) NULL;
258         win->classvec = (char *) NULL;
259         win->scorevec = (double *) NULL;
260
261         stateon(win);
262
263         return win;
264 }
265
266 /*---------------------------------------------------------------(nextwin)---*/
267
268 extern struct Sequence *nextwin(win, shift)
269   struct Sequence *win;
270   int shift;
271
272   {
273    if ((win->start+shift)<0 ||
274        (win->start+win->length+shift)>win->parent->length)
275      {
276       return((struct Sequence *) NULL);
277      }
278    else
279      {
280       return(openwin(win->parent, win->start+shift, win->length));
281      }
282   }
283
284 /*--------------------------------------------------------------(shiftwin1)---*/
285 static void     decrementsv(), incrementsv();
286
287 extern int shiftwin1(win)
288         struct Sequence *win;
289 {
290         register int    j, length;
291         register int    *comp;
292
293         length = win->length;
294         comp = win->composition;
295
296         if ((++win->start + length) > win->parent->length) {
297                 --win->start;
298                 return FALSE;
299         }
300
301         if (!aaflag[j = win->seq[0]])
302                 decrementsv(win->state, comp[aaindex[j]]--);
303
304         j = win->seq[length];
305         ++win->seq;
306
307         if (!aaflag[j])
308                 incrementsv(win->state, comp[aaindex[j]]++);
309
310         if (win->entropy > -2.)
311                 win->entropy = entropy(win->state);
312
313         return TRUE;
314 }
315
316 /*--------------------------------------------------------------(closewin)---*/
317
318 extern closewin(win)
319   struct Sequence *win;
320
321   {
322    if (win==NULL) return;
323
324    if (win->state!=NULL)       free(win->state);
325    if (win->composition!=NULL) free(win->composition);
326    if (win->classvec!=NULL)    free(win->classvec);
327    if (win->scorevec!=NULL)    free(win->scorevec);
328
329    free(win);
330    return;
331   }
332
333 /*----------------------------------------------------------------(compon)---*/
334
335 extern compon(win)
336         struct Sequence *win;
337 {
338         register int    *comp;
339         register int    aa;
340         register char   *seq, *seqmax;
341
342         win->composition = comp = (int *) calloc(20*sizeof(*comp), 1);
343         seq = win->seq;
344         seqmax = seq + win->length;
345
346         while (seq < seqmax) {
347                 aa = *seq++;
348                 if (!aaflag[aa])
349                         comp[aaindex[aa]]++;
350         }
351
352         return;
353 }
354
355 /*---------------------------------------------------------------(stateon)---*/
356
357 static int state_cmp(s1, s2)
358         int     *s1, *s2;
359 {
360         return *s2 - *s1;
361 }
362
363 extern stateon(win)
364         struct Sequence *win;
365 {
366         register int    aa, nel, c;
367
368         if (win->composition == NULL)
369                 compon(win);
370
371         win->state = (int *) malloc(21*sizeof(win->state[0]));
372
373         for (aa = nel = 0; aa < 20; ++aa) {
374                 if ((c = win->composition[aa]) == 0)
375                         continue;
376                 win->state[nel++] = c;
377         }
378         for (aa = nel; aa < 21; ++aa)
379                 win->state[aa] = 0;
380
381         qsort(win->state, nel, sizeof(win->state[0]), state_cmp);
382
383         return;
384 }
385
386 /*-----------------------------------------------------------------(enton)---*/
387
388 extern enton(win)
389   struct Sequence *win;
390
391   {
392    if (win->state==NULL) {stateon(win);}
393
394    win->entropy = entropy(win->state);
395
396    return;
397   }
398
399 /*---------------------------------------------------------------(entropy)---*/
400 static int              thewindow;
401 static double   *entray;
402
403 #define LN2     0.69314718055994530941723212145818
404
405 void
406 entropy_init(window)
407         int     window;
408 {
409         int             i;
410         double  x, xw;
411
412         entray = (double *)malloc((window+1) * sizeof(*entray));
413         xw = window;
414         for (i = 1; i <= window; ++i) {
415                 x = i / xw;
416                 entray[i] = -x * log(x) / LN2;
417         }
418
419         thewindow = window;
420 }
421
422 extern double entropy(sv)
423         register int    *sv;
424 {
425         int     *sv0 = sv;
426         register double ent;
427         register int    i, total;
428         register int    *svmax;
429         register double xtotrecip, xsv;
430
431         for (total = 0; (i = *sv) != 0; ++sv)
432                 total += i;
433         svmax = sv;
434         ent = 0.0;
435         if (total == thewindow) {
436                 for (sv = sv0; sv < svmax; ) {
437                         ent += entray[*sv++];
438                 }
439                 return ent;
440         }
441         if (total == 0)
442                 return 0.;
443
444         xtotrecip = 1./(double)total;
445         for (sv = sv0; sv < svmax; ) {
446                 xsv = *sv++;
447                 ent += xsv * log(xsv * xtotrecip);
448         }
449         return -ent * xtotrecip / LN2;
450 }
451
452 /*-----------------------------------------------------------(decrementsv)---*/
453
454 static void
455 decrementsv(sv, class)
456         register int    *sv;
457         register int    class;
458 {
459         register int    svi;
460
461         while ((svi = *sv++) != 0) {
462                 if (svi == class && *sv < class) {
463                         sv[-1] = svi - 1;
464                         break;
465                 }
466         }
467 }
468
469 /*-----------------------------------------------------------(incrementsv)---*/
470
471 static void
472 incrementsv(sv, class)
473         register int    *sv;
474         int     class;
475 {
476         for (;;) {
477                 if (*sv++ == class) {
478                         sv[-1]++;
479                         break;
480                 }
481         }
482 }
483
484 /*-------------------------------------------------------------(readentry)---*/
485
486 struct Sequence *readentry(dbase)
487   struct Database *dbase;
488
489   {struct Sequence *seq;
490    int  c;
491
492    seq = (struct Sequence *) malloc(sizeof(struct Sequence));
493
494    seq->db = dbase;
495
496 /*---                                    ---[backpointers null at the top]---*/
497
498    seq->parent = (struct Sequence *) NULL;
499    seq->root = (struct Sequence *) NULL;
500    seq->children = (struct Sequence **) NULL;
501
502 /*---                                                       ---[set flags]---*/
503
504    seq->rubberwin = FALSE;
505    seq->floatwin = FALSE;
506
507 /*---                                                  ---[read from file]---*/
508
509    if (!readhdr(seq))
510      {
511       return((struct Sequence *) NULL);
512      }
513    while (1)  /*---[skip multiple headers]---*/
514      {
515       c = getc(dbase->fp);
516           if (c == EOF)
517                 break;
518       if (c != '>') {
519          ungetc(c, dbase->fp);
520          break;
521                 }
522       while ((c=getc(dbase->fp)) != EOF && c !='\n')
523                 ;
524                 if (c == EOF)
525                         break;
526      }
527    readseq(seq);
528
529 /*---                                   ---[set implementation parameters]---*/
530
531 /*---                                          ---[initially unconfigured]---*/
532
533    seq->entropy = -2.;
534    seq->state = (int *) NULL;
535    seq->composition = (int *) NULL;
536    seq->classvec = (char *) NULL;
537    seq->scorevec = (double *) NULL;
538
539    return(seq);
540   }
541
542 /*---------------------------------------------------------------(readhdr)---*/
543
544 readhdr(seq)
545   struct Sequence *seq;
546
547   {FILE *fp;
548    char *bptr, *curpos;
549    int  c, i, itotal;
550    int idend, namend, orgend;
551
552    fp = seq->db->fp;
553
554    if ((c=getc(fp)) == EOF)
555      {
556       free(seq);
557       return(FALSE);
558      }
559    
560    while (c != EOF && isspace(c))
561      {
562       c = getc(fp);
563      }
564
565    if (c!='>')
566      {fprintf(stderr, "Error reading fasta format - '>' not found.\n");
567       exit(1);}
568    ungetc(c, fp);
569 /*                                               ---[read the header line]---*/
570    str = (struct strlist *) malloc (sizeof(struct strlist));
571    str->next = NULL;
572    curstr = str;
573
574    for (i=0,itotal=0,c=getc(fp); c != EOF; c=getc(fp))
575      {
576       if (c=='\n') break;
577
578       if (i==STRSIZE-1)
579         {curstr->string[i] = '\0';
580          curstr->next = (struct strlist *) malloc (sizeof(struct strlist));
581          curstr = curstr->next;
582          curstr->next = NULL;
583          i = 0;}
584
585       curstr->string[i] = c;
586       itotal++;
587       i++;
588      }
589
590    curstr->string[i] = '\0';
591    seq->header = (char *) malloc (itotal+2);
592    seq->header[0] = '\0';
593
594    for (curstr=str, curpos=seq->header; curstr!=NULL;)
595      {
596       if (curstr->next==NULL)
597         {memccpy(curpos, curstr->string, '\0', STRSIZE);}
598       else
599         {memccpy(curpos, curstr->string, '\0', STRSIZE-1);}
600
601       str = curstr;
602       curstr = curstr->next;
603       free (str);
604
605       if (curstr!=NULL) {curpos = curpos+STRSIZE-1;}
606      }
607
608    bptr = (seq->header)+1;
609    seq->name = (char *) NULL;
610    seq->organism = (char *) NULL;
611 /*                                                   ---[parse out the id]---*/
612    idend = findchar(bptr, ' ');
613    if (idend==-1) {idend = findchar(bptr, '\n');}
614    if (idend==-1) {idend = findchar(bptr, '\0');}
615    if (idend==-1)
616      {fprintf(stderr, "Error parsing header line - id.\n");
617       fputs(seq->header, fp);
618       exit(1);}   
619
620    seq->id = (char *) malloc((idend+1)*sizeof(char));
621    memcpy(seq->id, bptr, idend);
622    seq->id[idend] = '\0';
623
624    if (bptr[idend]=='\n' || bptr[idend]=='\0') {return(TRUE);}
625
626 /*                                         ---[parse out the protein name]---*/
627    bptr = bptr + idend + 1;
628    while (bptr[0]==' ') {bptr++;}
629
630    namend = findchar(bptr, '-');
631    if (namend==-1) {namend = findchar(bptr, '\n');}
632    if (namend==-1) {namend = findchar(bptr, '\0');}
633    if (namend==-1)
634      {fprintf(stderr, "Error parsing header line - name.\n");
635       fputs(seq->header, fp);
636       return(TRUE);}
637
638    seq->name = (char *) malloc((namend+1)*sizeof(char));
639    memcpy(seq->name, bptr, namend);
640    seq->name[namend] = '\0';
641
642    if (bptr[namend]=='\n' || bptr[namend]=='\0') {return(TRUE);}
643
644 /*                                                 ---[parse out organism]---*/
645    bptr = bptr + namend + 1;
646    while (bptr[0]==' ') {bptr++;}
647
648    orgend = findchar(bptr, '|');
649    if (orgend==-1) {orgend = findchar(bptr, '#');}
650    if (orgend==-1) {orgend = findchar(bptr, '\n');}
651    if (orgend==-1) {orgend = findchar(bptr, '\0');}
652    if (orgend==-1)
653      {fprintf(stderr, "Error parsing header line - organism.\n");
654       fputs(seq->header, fp);
655       return(TRUE);}
656
657    seq->organism = (char *) malloc((orgend+1)*sizeof(char));
658    memcpy(seq->organism, bptr, orgend);
659    seq->organism[orgend] = '\0';
660
661 /*                                    ---[skip over multiple header lines]---*/
662    while (TRUE)
663      {
664       c = getc(fp);
665           if (c == EOF)
666                 return(TRUE);
667       if (c=='>')
668         {
669          skipline(fp);
670         }
671       else
672         {
673          ungetc(c,fp);
674          break;
675         }
676      }
677
678    return(TRUE);
679   }
680
681 /*--------------------------------------------------------------(skipline)---*/
682
683 skipline(fp)
684   FILE *fp;
685
686   {int  c;
687
688    while ((c=getc(fp))!='\n' && c!=EOF)
689      ;
690
691    return;
692   }
693
694 /*--------------------------------------------------------------(findchar)---*/
695
696 extern int findchar(str, chr)
697   char *str;
698   char chr;
699
700   {int i;
701
702    for (i=0; ; i++)
703      {
704       if (str[i]==chr)
705         {
706          return(i);
707         }
708       if (str[i]=='\0')
709         {
710          return(-1);
711         }
712      }
713    }
714
715 /*---------------------------------------------------------------(readseq)---*/
716
717 readseq(seq)
718   struct Sequence *seq;
719
720 {FILE *fp;
721    int i, itotal;
722    int  c;
723    char *curpos;
724
725    fp = seq->db->fp;
726
727    seq->punctuation = FALSE;   
728
729    str = (struct strlist *) malloc (sizeof(struct strlist));
730    str->next = NULL;
731    curstr = str;
732
733         for (i = 0, itotal = 0, c = getc(fp); c != EOF; c = getc(fp)) {
734                 if (!aaflag[c]) {
735 Keep:
736                         if (i < STRSIZE-1) {
737                                 curstr->string[i++] = c;
738                                 continue;
739                         }
740                         itotal += STRSIZE-1;
741                         curstr->string[STRSIZE-1] = '\0';
742                         curstr->next = (struct strlist *) malloc(sizeof(*curstr));
743                         curstr = curstr->next;
744                         curstr->next = NULL;
745                         curstr->string[0] = c;
746                         i = 1;
747                         continue;
748         }
749
750                 switch (c) {
751                 case '>':
752                         ungetc(c, fp);
753                         goto EndLoop;
754                 case '*': case '-':
755                         seq->punctuation = TRUE;
756                         goto Keep;
757                 case 'b': case 'B':
758                 case 'u': case 'U': /* selenocysteine */
759                 case 'x': case 'X':
760                 case 'z': case 'Z':
761                         goto Keep;
762                 default:
763                         continue;
764                 }
765         }
766 EndLoop:
767         itotal += i;
768
769         curstr->string[i] = '\0';
770         seq->seq = (char *) malloc (itotal+2);
771         seq->seq[0] = '\0';
772
773         for (curstr = str, curpos = seq->seq; curstr != NULL;) {
774                 if (curstr->next == NULL)
775                         memccpy(curpos, curstr->string, '\0', STRSIZE);
776                 else
777                 memccpy(curpos, curstr->string, '\0', STRSIZE-1);
778
779                 str = curstr;
780                 curstr = curstr->next;
781                 free(str);
782
783                 if (curstr != NULL)
784                         curpos = curpos+STRSIZE-1;
785         }
786
787         seq->length = strlen(seq->seq);
788
789         return;
790 }
791 /*-----------------------------------------------------------------(upper)---*/
792
793 extern upper(string, len)
794         register char   *string;
795         size_t  len;
796 {
797         register char   *stringmax, c;
798
799         for (stringmax = string + len; string < stringmax; ++string)
800                 if (islower(c = *string))
801                         *string = toupper(c);
802 }
803
804 /*-----------------------------------------------------------------(lower)---*/
805
806 extern lower(string, len)
807         char    *string;
808         size_t  len;
809 {
810         register char   *stringmax, c;
811
812         for (stringmax = string + len; string < stringmax; ++string)
813                 if (isupper(c = *string))
814                         *string = tolower(c);
815 }
816
817 /*-------------------------------------------------------------------(min)---*/
818
819 int min(a, b)
820   int a, b;
821
822   {
823    if (a<b) {return(a);}
824    else {return(b);}
825   }
826
827 /*-------------------------------------------------------------------(max)---*/
828
829 int max(a, b)
830   int a, b;
831
832   {
833    if (a<b) {return(b);}
834    else {return(a);}
835   }
836
837 /*---------------------------------------------------------------------------*/
838
839 /*---------------------------------------------------------------(tmalloc)---*/
840
841 void *tmalloc(size)
842   size_t size;
843
844   {void *ptr;
845
846    ptr = (void *) malloc(size);
847
848    if (rptr>TESTMAX)
849      {
850       exit(2);
851      }
852
853    record_ptrs[rptr] = (int) ptr;
854    rptr++;
855
856    return(ptr);
857   }
858
859 /*-----------------------------------------------------------------(tfree)---*/
860
861 tfree(ptr)
862   void *ptr;
863
864   {int i;
865
866    for (i=0; i<rptr; i++)
867      {
868       if (record_ptrs[i]==(int)ptr)
869         {
870          record_ptrs[i] = 0;
871          break;
872         }
873       }
874
875    free(ptr);
876   }
877
878 /*---------------------------------------------------------------------------*/