JPRED-2 Add sources of all binaries (except alscript) to Git
[jpred.git] / sources / seg / hiseg.c
1
2 /*****************************************************************************/
3 /***  (hiseg.c)                                                            ***/
4 /*** #include precomputed ln(fact(n)) array in "lnfac.h"                   ***/
5 /*****************************************************************************/
6
7 /*--------------------------------------------------------------(includes)---*/
8
9 #include "genwin.h"
10 #include "lnfac.h"
11
12 /*---------------------------------------------------------------(defines)---*/
13
14 #define LENCORRLIM 120
15 #define MIN(a,b)        ((a) <= (b) ? (a) : (b))
16
17 /*---------------------------------------------------------------(structs)---*/
18
19 struct Segment
20   {
21    int begin;
22    int end;
23    struct Segment *next;
24   };
25
26 /*---------------------------------------------------------------(globals)---*/
27
28 int window = 12;
29 int downset, upset;
30 double hicut = 2.5;
31 double locut = 2.2;
32
33 int hilenmin = 0;
34 int overlaps = FALSE;
35 int hionly = FALSE;
36 int loonly = FALSE;
37 int entinfo = TRUE;
38 int singleseq = FALSE;
39 int prettyseq = FALSE;
40 int prettytree = TRUE;
41 int charline = 60;
42 int maxtrim = 100;
43
44 double getK1(), getprob(), lnperm(), lnass();
45
46 /*------------------------------------------------------------------(main)---*/
47
48 main(argc, argv)
49   int argc;
50   char *argv[];
51
52   {struct Database *db;
53    struct Sequence *seq;
54    struct Segment *segs;
55    int ctime;
56
57    genwininit();
58 /* readlencorr(); */                        /* #include lencorr file */
59    getparams(argc, argv);
60    entropy_init(window);
61
62    if ((db=opendbase(argv[1]))==NULL)
63      {
64       fprintf(stderr, "Error opening file %s\n", argv[1]);
65       exit(1);
66      }
67
68    for (seq=firstseq(db); seq!=NULL; seq=nextseq(db))
69      {
70       segs = (struct Segment *) NULL;
71       segseq(seq, &segs, 0);
72       mergesegs(seq, segs);
73
74       if (singleseq) singreport(seq, segs);
75       else if (prettyseq) prettyreport(seq, segs);
76       else if (prettytree) pretreereport(seq, segs);
77       else report(seq, segs);
78
79       freesegs(segs);
80       closeseq(seq);
81      }
82
83    closedbase(db);
84    exit(0);
85   }
86
87 /*-------------------------------------------------------------(getparams)---*/
88
89 getparams(argc, argv)
90   int argc;
91   char *argv[];
92
93   {int i;
94    int nargc;
95    char **nargv;
96    extern char *optarg;
97    extern int optind;
98    int c;
99
100    if (argc<2)
101      {
102       usage();
103       exit(1);
104      }
105
106    for (i=2; argc>i && argv[i][0]!='-'; i++)
107      {
108       if (i==2)
109         {
110          window = atoi(argv[2]);
111         }
112       else if (i==3)
113         {
114          hicut = atof(argv[3]);  /*- trigger is now 'hicut' -*/
115         }
116       else if (i==4)
117         {
118          locut = atof(argv[4]); /*- extension is now 'locut' -*/
119         }
120      }
121
122    if (locut>hicut)
123      {
124       fprintf(stderr, "Warning: trigger complexity less than extension\n");
125       locut = hicut;
126      }
127
128    downset = (window+1)/2 - 1;
129    upset = window - downset;
130
131    if (i==argc) return;
132
133    nargc = argc-i+1;
134    nargv = argv+(i-1);
135    while ((c=getopt(nargc, nargv, "m:olhaxpqc:nt:"))!=-1)
136      {
137       switch(c)
138         {
139          case 'm':
140             hilenmin = atoi(optarg);
141             break;
142          case 'o':
143             overlaps = TRUE;
144             hilenmin = 0;
145             break;
146          case 'l':
147             loonly = TRUE;
148             singleseq = FALSE;
149             prettyseq = FALSE;
150             prettytree = FALSE;
151             break;
152          case 'h':
153             hionly = TRUE;
154             singleseq = FALSE;
155             prettyseq = FALSE;
156             prettytree = FALSE;
157             break;
158          case 'a':
159             hionly = FALSE;
160             loonly = FALSE;
161             singleseq = FALSE;
162             prettyseq = FALSE;
163             prettytree = FALSE;
164             break;
165          case 'x':
166             singleseq = TRUE;
167             prettyseq = FALSE;
168             prettytree = FALSE;
169             hionly = TRUE;
170             loonly = FALSE;
171             break;
172          case 'p':
173             prettytree = TRUE;
174             prettyseq = FALSE;
175             singleseq = FALSE;
176             hionly = FALSE;
177             loonly = FALSE;
178             break;
179          case 'q':
180             prettyseq = TRUE;
181             prettytree = FALSE;
182             singleseq = FALSE;
183             hionly = FALSE;
184             loonly = FALSE;
185             break;
186          case 'c':
187             charline = atoi(optarg);
188             break;
189          case 'n':
190             entinfo = FALSE;
191             break;
192          case 't':
193             maxtrim = atoi(optarg);
194             break;
195          case '?':
196             fprintf(stderr, "Unknown option.\n");
197             usage();
198             exit(1);
199             break;
200         }
201      }   
202
203    return;
204   }
205
206 /*---------------------------------------------------------------(segment)---*/
207
208 segseq(seq, segs, offset)
209   struct Sequence *seq;
210   struct Segment **segs;
211   int offset;
212
213   {struct Segment *seg, *leftsegs;
214    struct Sequence *leftseq;
215    int first, last, lowlim;
216    int loi, hii, i;
217    int leftend, rightend, lend, rend;
218    double *H, *seqent();
219
220    H = seqent(seq);
221    if (H==NULL) return;
222
223    first = downset;
224    last = seq->length - upset;
225    lowlim = first;
226
227    for (i=first; i<=last; i++)
228      {
229       if (H[i]>=hicut && H[i]!=-1)
230         {
231          loi = findlo(i, lowlim, H);
232          hii = findhi(i, last, H);
233
234          leftend = loi - downset;
235          rightend = hii + upset - 1;
236
237          trim(openwin(seq, leftend, rightend-leftend+1), &leftend, &rightend);
238
239          if (i+upset-1<leftend)   /* check for trigger window in left trim */
240            {
241             lend = loi - downset;
242             rend = leftend - 1;
243
244             leftseq = openwin(seq, lend, rend-lend+1);
245             leftsegs = (struct Segment *) NULL;
246             segseq(leftseq, &leftsegs, offset+lend);
247             if (leftsegs!=NULL)
248               {
249                if (*segs==NULL) *segs = leftsegs;
250                else appendseg(*segs, leftsegs);
251               }
252             closewin(leftseq);
253
254 /*          trim(openwin(seq, lend, rend-lend+1), &lend, &rend);
255             seg = (struct Segment *) malloc(sizeof(struct Segment));
256             seg->begin = lend;
257             seg->end = rend;
258             seg->next = (struct Segment *) NULL;
259             if (segs==NULL) segs = seg;
260             else appendseg(segs, seg);  */
261            }
262
263          seg = (struct Segment *) malloc(sizeof(struct Segment));
264          seg->begin = leftend + offset;
265          seg->end = rightend + offset;
266          seg->next = (struct Segment *) NULL;
267
268          if (*segs==NULL) *segs = seg;
269          else appendseg(*segs, seg);
270
271          i = min(hii, rightend+downset);
272          lowlim = i + 1;
273 /*       i = hii;     this ignores the trimmed residues... */
274         }
275      }
276
277    free(H);
278    return;
279   }
280
281 /*----------------------------------------------------------------(seqent)---*/
282
283 double *seqent(seq)
284   struct Sequence *seq;
285
286   {struct Sequence *win;
287    double *H;
288    int i, first, last;
289
290    if (window>seq->length)
291      {
292       return((double *) NULL);
293      }
294
295    H = (double *) malloc(seq->length*sizeof(double));
296
297    for (i=0; i<seq->length; i++)
298      {
299       H[i] = -1.;
300      }
301
302    win = openwin(seq, 0, window);
303    enton(win);
304
305    first = downset;
306    last = seq->length - upset;
307
308    for (i=first; i<=last; i++)
309      {
310       if (seq->punctuation && hasdash(win))
311         {H[i] = -1;
312          shiftwin1(win);
313          continue;}
314       H[i] = win->entropy;
315       shiftwin1(win);
316      }
317
318    closewin(win);
319    return(H);
320   }
321
322 /*---------------------------------------------------------------(hasdash)---*/
323
324 hasdash(win)
325   struct Sequence *win;
326 {
327         register char   *seq, *seqmax;
328
329         seq = win->seq;
330         seqmax = seq + win->length;
331
332         while (seq < seqmax) {
333                 if (*seq++ == '-')
334                         return TRUE;
335         }
336         return FALSE;
337 }
338
339 /*----------------------------------------------------------------(findlo)---*/
340
341 findlo(i, limit, H)
342   int i, limit;
343   double *H;
344
345   {int j;
346
347    for (j=i; j>=limit; j--)
348      {
349       if (H[j]==-1) break;
350       if (H[j]<locut) break;
351      }
352
353    return(j+1);
354   }
355
356 /*----------------------------------------------------------------(findhi)---*/
357
358 findhi(i, limit, H)
359   int i, limit;
360   double *H;
361
362   {int j;
363
364    for (j=i; j<=limit; j++)
365      {
366       if (H[j]==-1) break;
367       if (H[j]<locut) break;
368      }
369
370    return(j-1);
371   }
372
373 /*------------------------------------------------------------------(trim)---*/
374
375 trim(seq, leftend, rightend)
376   struct Sequence *seq;
377   int *leftend, *rightend;
378
379   {struct Sequence *win;
380    double K1, maxK1;
381    int shift, len, i;
382    int lend, rend;
383    int minlen;
384
385 /* fprintf(stderr, "%d %d\n", *leftend, *rightend);  */
386
387    lend = 0;
388    rend = seq->length - 1;
389    minlen = 1;
390    if ((seq->length-maxtrim)>minlen) minlen = seq->length-maxtrim;
391
392    maxK1 = 0.;
393    for (len=seq->length; len>minlen; len--)
394      {
395       win = openwin(seq, 0, len);
396       stateon(win);
397       i = 0;
398
399       shift = TRUE;
400       while (shift)
401         {
402          K1 = getK1(win->state, len);
403          if (K1>maxK1)
404            {
405             maxK1 = K1;
406             lend = i;
407             rend = len + i - 1;
408            }
409          shift = shiftwin1(win);
410          i++;
411         }
412       closewin(win);
413      }
414
415 /* fprintf(stderr, "%d-%d ", *leftend, *rightend);  */
416
417    *leftend = *leftend + lend;
418    *rightend = *rightend - (seq->length - rend - 1);
419
420 /* fprintf(stderr, "%d-%d\n", *leftend, *rightend);  */
421
422    closewin(seq);
423    return;
424   }
425
426 /*---------------------------------------------------------------(getprob)---*/
427
428 double getprob(sv, total)
429   int *sv;
430   int total;
431
432   {double ans, totseq;
433
434 #define LN20    2.9957322735539909
435    totseq = ((double) total) * LN20;
436
437    ans = lnass(sv) + lnperm(sv, total) - totseq;
438
439    return(ans);
440   }
441
442 /*-----------------------------------------------------------------(getK1)---*/
443
444 double getK1(sv, total)
445   int *sv;
446   int total;
447
448   {double ans;
449
450    ans = lnperm(sv, total) / ((double) total);
451
452    return(ans);
453   }
454
455 /*----------------------------------------------------------------(lnperm)---*/
456
457 double lnperm(sv, tot)
458   int *sv;
459    int tot;
460
461   {double ans;
462    int i;
463
464    ans = lnfac[tot];
465
466    for (i=0; sv[i]!=0; i++) 
467      {
468       ans -= lnfac[sv[i]];
469      }
470
471    return(ans);
472   }
473
474 /*-----------------------------------------------------------------(lnass)---*/
475
476 double lnass(sv)
477         register int    *sv;
478 {
479         double  ans;
480         register int    svi, svim1;
481         register int    class, total;
482         register int    i;
483
484         ans = lnfac[20];
485         if (sv[0] == 0)
486                 return ans;
487
488         total = 20;
489         class = 1;
490         svim1 = sv[0];
491         for (i=0;; svim1 = svi) {
492                 if (++i==20) {
493                         ans -= lnfac[class];
494                         break;
495                       }
496                 else if ((svi = *++sv) == svim1) {
497                         class++;
498                         continue;
499                 }
500                 else {
501                         total -= class;
502                         ans -= lnfac[class];
503                         if (svi == 0) {
504                                 ans -= lnfac[total];
505                                 break;
506                         }
507                         else {
508                                 class = 1;
509                                 continue;
510                         }
511                 }
512         }
513
514         return ans;
515 }
516
517 /*-------------------------------------------------------------(mergesegs)---*/
518
519 mergesegs(seq, segs)
520   struct Sequence *seq;
521   struct Segment *segs;
522
523   {struct Segment *seg, *nextseg;
524    int len;
525
526    if (overlaps) return;
527    if (segs==NULL) return;
528
529    if (segs->begin<hilenmin) segs->begin = 0;
530
531    seg = segs;
532    nextseg = seg->next;
533
534    while (nextseg!=NULL)
535      {
536       if (seg->end>=nextseg->begin)               /* overlapping segments */
537         {
538          seg->end = nextseg->end;
539          seg->next = nextseg->next;
540          free(nextseg);
541          nextseg = seg->next;
542          continue;
543         }
544       len = nextseg->begin - seg->end - 1;
545       if (len<hilenmin)                            /* short hient segment */
546         {
547          seg->end = nextseg->end;
548          seg->next = nextseg->next;
549          free(nextseg);
550          nextseg = seg->next;
551          continue;
552         }
553       seg = nextseg;
554       nextseg = seg->next;
555      }
556
557    len = seq->length - seg->end - 1;
558    if (len<hilenmin) seg->end = seq->length - 1;
559
560    return;
561   }
562
563 /*----------------------------------------------------------------(report)---*/
564
565 report(seq, segs)
566   struct Sequence *seq;
567   struct Segment *segs;
568
569   {struct Sequence *subseq;
570    struct Segment *seg, *nextseg;
571    static int hi = 1;
572    static int lo = 0;
573
574    if (segs==NULL)
575      {
576       enton(seq);
577       seqout(seq, hi, 1, seq->length);
578 /*    fputc('\n', stdout);   -- for spacing after each sequence */
579       return;
580      }
581
582    if (segs->begin>0)
583      {
584       subseq = openwin(seq, 0, segs->begin);
585       enton(subseq);
586       seqout(subseq, hi, 1, segs->begin);
587       closewin(subseq);
588      }
589
590    for (seg=segs; seg!=NULL; seg=seg->next)
591      {
592       subseq = openwin(seq, seg->begin, seg->end-seg->begin+1);
593       enton(subseq);
594       seqout(subseq, lo, seg->begin+1, seg->end+1);
595       closewin(subseq);
596
597       if (seg->next==NULL)
598         {
599          break;
600         }
601
602       nextseg = seg->next;
603       
604       if (nextseg->begin<=seg->end)
605         {
606          fprintf(stderr, "Overlapping segments: %s\n", seq->id);
607          continue;
608         }
609
610       if (nextseg->begin==seg->end+1)
611         {
612          continue;
613         }
614
615       subseq = openwin(seq, seg->end+1, nextseg->begin-seg->end-1);
616       enton(subseq);
617       seqout(subseq, hi, seg->end+2, nextseg->begin);
618       closewin(subseq);
619      }
620
621    if (seg->end+1==seq->length)
622      {
623 /*    fputc('\n', stdout);   -- for spacing after each sequence */
624       return;
625      }
626
627    subseq = openwin(seq, seg->end+1, seq->length-seg->end-1);
628    enton(subseq);
629    seqout(subseq, hi, seg->end+2, seq->length);
630    closewin(subseq);
631
632 /* fputc('\n', stdout);   -- for spacing after each sequence */
633    return;
634   }
635
636 /*------------------------------------------------------------(singreport)---*/
637
638 singreport(seq, segs)
639         struct Sequence *seq;
640         struct Segment  *segs;
641 {
642         char    *proseq, *proseqmax;
643         struct Segment  *seg;
644         int     begin, end, i, ctr;
645
646         proseq = seq->seq;
647         proseqmax = proseq + seq->length;
648         upper(proseq, seq->length);
649
650         for (seg=segs; seg!=NULL; seg=seg->next) {
651                 begin = seg->begin;
652                 end = seg->end;
653                 memset(proseq + begin, 'x', end - begin +1);
654         }
655
656         fprintf(stdout, "%s\n", seq->header);
657
658         for (i=0, ctr=0; proseq < proseqmax; ++i, ++ctr, ++proseq) {
659                 if (ctr==charline) {
660                         putc('\n', stdout);
661                         ctr = 0;
662                 }
663                 putc(*proseq, stdout);
664         }
665
666         putc('\n', stdout);
667         if (putc('\n', stdout) == EOF) {
668                 fprintf(stderr, "premature EOF on write\n");
669                 exit(2);
670         }
671 }
672
673 /*----------------------------------------------------------(prettyreport)---*/
674
675 prettyreport(seq, segs)
676   struct Sequence *seq;
677   struct Segment *segs;
678
679 {
680         char    *proseq, *proseqmax;
681         char    format[10];
682         struct Segment  *seg;
683         int     begin, end, i, ctr;
684         int     leftspace;
685
686         leftspace = (int) ceil(log10((double)seq->length));
687         sprintf(format, "%%%dd ", leftspace);
688
689         upper(proseq = seq->seq, seq->length);
690
691         for (seg=segs; seg!=NULL; seg=seg->next) {
692                 begin = seg->begin;
693                 end = seg->end;
694                 lower(proseq + begin, end - begin + 1);
695         }
696
697         fprintf(stdout, "%s\n", seq->header);
698
699         space(leftspace+1);
700         for (i=0, ctr=1; i<charline; ++i, ++ctr) {
701                 if (ctr==10) {
702                         putc('.', stdout);
703                         ctr = 0;
704                 }
705                 else
706                         putc(' ', stdout);
707         }
708         putc('\n', stdout);
709         fprintf(stdout, format, 1);
710
711         proseqmax = proseq + seq->length;
712         for (i=0, ctr=0; proseq < proseqmax; ++i, ++ctr, ++proseq) {
713                 if (ctr==charline) {
714                         putc('\n', stdout);
715                         fprintf(stdout, format, i+1);
716                         ctr = 0;
717                 }
718                 putc(*proseq, stdout);
719         }
720
721         fprintf(stdout, " %d\n", seq->length);
722         if (putc('\n', stdout) == EOF) {
723                 fprintf(stderr, "premature EOF on write\n");
724                 exit(2);
725         }
726 }
727
728 /*---------------------------------------------------------(pretreereport)---*/
729
730 pretreereport(seq, segs)
731   struct Sequence *seq;
732   struct Segment *segs;
733
734 {
735         struct Sequence *win;
736         struct Segment  *seg;
737         char    buffer[100], leftfmt[20], rightfmt[20];
738         char    *curseq;
739         int     i, left, right, len;
740         int     current, nextloent;
741         int     cline;
742
743         cline = charline / 2;
744    
745         fprintf(stdout, "%s\n\n", seq->header);
746         sprintf(leftfmt, "%%%ds", cline);
747         sprintf(rightfmt, "%%-%ds", cline);
748
749         current = 0;
750
751         for (seg=segs; ; seg=seg->next) {
752                 if (seg==NULL)
753                         nextloent = seq->length;
754                 else
755                         nextloent = seg->begin;
756
757                 if (current < nextloent) {
758                         left = current;
759                         right = nextloent - 1;
760                         len = right - left + 1;
761                         win = openwin(seq, left, len);
762                         upper(curseq = win->seq, win->length);
763
764                         space(cline);
765                         fprintf(stdout, " %4d-%-4d ", left+1, right+1);
766
767                         while (len>0) {
768                                 if (len<=cline) {
769                                         fwrite(curseq, len, 1, stdout);
770                                         putc('\n', stdout);
771                                         break;
772                                 }
773                                 else {
774                                         fwrite(curseq, cline, 1, stdout);
775                                         putc('\n', stdout);
776                                         space(cline+11);
777                                         curseq += cline;
778                                         len -= cline;
779                                 }
780                         }
781                         closewin(win);
782                 }
783
784                 if (seg==NULL) break;
785
786       left = seg->begin;
787       right = seg->end;
788       len = right - left + 1;
789       win = openwin(seq, left, len);
790       lower(curseq = win->seq, win->length);
791
792                 i = MIN(cline, len);
793                 if (i < cline)
794                         fprintf(stdout, "%*s", cline-i, "");
795                 fwrite(curseq, i, 1, stdout);
796                 fprintf(stdout, " %4d-%-4d ", left+1, right+1);
797                 putc('\n', stdout);
798
799                 len -= cline;
800                 if (len>0)
801                         curseq += cline;
802
803                 while (len>0) {
804                         i = MIN(cline, len);
805                         if (i < cline)
806                                 space(cline - i);
807                         fwrite(curseq, i, 1, stdout);
808                         putc('\n', stdout);
809                         len -= i;
810                         if (len>0)
811                                 curseq += i;
812                 }
813
814                 closewin(win);
815                 current = right + 1;
816         }
817
818         putc('\n', stdout);
819 }
820
821 /*-----------------------------------------------------------------(space)---*/
822
823 space(len)
824         register int len;
825 {
826         static char     spaces[] =
827                 {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
828                 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
829                 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
830                 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
831                 ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '
832                 };
833         register int i;
834
835         while (len > 0) {
836                 i = MIN(len, sizeof(spaces)/sizeof(spaces[0]));
837                 fwrite(spaces, i, 1, stdout);
838                 len -= i;
839         }
840 }
841
842 /*----------------------------------------------------------------(seqout)---*/
843
844 seqout(seq, hilo, begin, end)
845   struct Sequence *seq;
846   int hilo;
847   int begin, end;
848
849 #define HDRLEN 60
850
851 {
852         char    *proseq, *proseqmax, *id, *header;
853    char outbuf[HDRLEN+1];
854    static int hi = 1;
855    static int lo = 0;
856    int i, ctr, iend;
857
858    if (hionly && hilo==lo) return;
859    if (loonly && hilo==hi) return;
860
861    proseq = seq->seq;
862    proseqmax = proseq + seq->length;
863    id = seq->id;
864    if (id==NULL) id = seq->parent->id;
865    header = seq->header;
866    if (header==NULL) header = seq->parent->header;
867
868    iend = findchar(header, ' ');
869    if (iend!=-1) header = header+iend;
870
871    if (entinfo)
872      {
873       fprintf(stdout, ">%s(%d-%d)", id, begin, end);
874 /*    if (iend!=-1 && strlen(header)<=HDRLEN) fprintf(stdout, "%s", header);
875       else if (iend!=-1) for (i=0; i<HDRLEN; i++) putc(header[i], stdout); */
876       fprintf(stdout, " complexity=%4.2f (%d/%4.2f/%4.2f)\n",
877            seq->entropy, window, locut, hicut);
878      }
879    else
880      {
881       fprintf(stdout, ">%s(%d-%d)", id, begin, end);
882       if (iend!=-1)   /* fprintf(stdout, "%s\n", header); */
883         {
884                  i = MIN(HDRLEN, strlen(header));
885                  fwrite(header, i, 1, stdout);
886          putc('\n', stdout);
887         }
888       else putc('\n', stdout);
889      }
890    
891    if (hilo==lo)
892      {
893       lower(proseq, seq->length);
894      }
895    else if (hilo==hi && seq->length>=hilenmin)
896      {
897       upper(proseq, seq->length);
898      }
899    else
900      {
901       lower(proseq, seq->length);
902      }
903
904    for (; proseq < proseqmax; proseq+=i) {
905                 i = MIN(charline, proseqmax - proseq);
906                 fwrite(proseq, i, 1, stdout);
907                 putc('\n', stdout);
908         }
909
910         if (putc('\n', stdout) == EOF) {
911                 fprintf(stderr, "premature EOF on write\n");
912                 exit(2);
913         }
914 }
915
916 /*-------------------------------------------------------------(appendseg)---*/
917
918 appendseg(segs, seg)
919   struct Segment *segs, *seg;
920
921   {struct Segment *temp;
922
923    temp = segs;
924    while (1)
925      {
926       if (temp->next==NULL)
927         {
928          temp->next = seg;
929          break;
930         }
931       else
932         {
933          temp = temp->next;
934         }
935      }
936
937    return;
938   }
939
940 /*--------------------------------------------------------------(freesegs)---*/
941
942 freesegs(segs)
943   struct Segment *segs;
944
945   {struct Segment *temp;
946
947    while (segs!=NULL)
948      {
949       temp = segs->next;
950       free(segs);
951       segs = temp;
952      }
953   }
954
955 /*-----------------------------------------------------------------(usage)---*/
956
957 usage()
958
959   {
960    fprintf(stderr, "\
961 Usage: hiseg <file> <window> <hicut> <locut> <options>\n\
962          <file>   - filename containing fasta-formatted sequence(s) \n\
963          <window> - OPTIONAL window size (default 12) \n\
964          <hicut>  - OPTIONAL high (trigger) complexity (default 2.5) \n\
965          <locut>  - OPTIONAL low (extension) complexity (default 2.2) \n\
966          <options> \n\
967             -x  each input sequence is represented by a single output \n\
968                 sequence with low-complexity regions replaced by \n\
969                 strings of 'x' characters \n\
970             -c <chars> number of sequence characters/line (default 60)\n\
971             -m <size> minimum length for a high-complexity segment \n\
972                 (default 0).  Shorter segments are merged with adjacent \n\
973                 low-complexity segments \n\
974             -l  show only low-complexity segments (fasta format) \n\
975             -h  show only high-complexity segments (fasta format) \n\
976             -a  show all segments (fasta format) \n\
977             -n  do not add complexity information to the header line \n\
978             -o  show overlapping low-complexity segments (default merge) \n\
979             -t <maxtrim> maximum trimming of raw segment (default 100) \n\
980             -p  prettyprint each segmented sequence (tree format) \n\
981             -q  prettyprint each segmented sequence (block format) \n");
982    exit(1);
983   }
984