root/trunk/ARB_GDE/GDE_FileIO.cxx

Revision 8642, 28.6 KB (checked in by westram, 5 weeks ago)
  • use result from fgets
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1#include "GDE_proto.h"
2#include <limits.h>
3#include <aw_msg.hxx>
4
5int MAX(int a, int b)
6{
7    if (a>b) return a;
8    return b;
9}
10
11static int MIN(int a, int b) {
12    if (a<b) return a;
13    return b;
14}
15
16void Regroup(NA_Alignment *alignment)
17{
18    size_t j;
19    size_t group;
20    int last;
21
22    for (j=0; j<alignment->numelements; j++)
23    {
24        alignment->element[j].groupf = NULL;
25        alignment->element[j].groupb = NULL;
26    }
27
28    for (group = 1; group <= alignment->numgroups; group++)
29    {
30        last = -1;
31        for (j=0; j<alignment->numelements; j++)
32            if (alignment->element[j].groupid == group)
33            {
34                if (last != -1)
35                {
36                    alignment->element[j].groupb =
37                        &(alignment->element[last]);
38                    alignment->element[last].groupf =
39                        &(alignment->element[j]);
40                }
41                last = j;
42            }
43    }
44    return;
45}
46
47
48void ErrorOut5(int code, const char *string)
49{
50    // Print error message, and die
51    if (code == 0)
52    {
53        fprintf(stderr, "Error:%s\n", string);
54        exit(1);
55    }
56    return;
57}
58
59
60char *Calloc(int count, int size)
61{
62    // More robust memory management routines
63    char *temp;
64    size *= count;
65#ifdef SeeAlloc
66    extern int TotalCalloc;
67    TotalCalloc += count*size;
68    fprintf(stderr, "Calloc %d %d\n", count*size, TotalCalloc);
69#endif
70    temp = (char *)malloc(size);
71    ErrorOut5(0 != temp, "Cannot allocate memory");
72    memset(temp, 0, size);
73    return (temp);
74}
75
76char *Realloc(char *block, int size)
77{
78    char       *temp;
79#ifdef SeeAlloc
80    extern int  TotalRealloc;
81    TotalRealloc += size;
82    fprintf(stderr, "Realloc %d\n", TotalRealloc);
83#endif
84    temp          = (char *)realloc(block, size);
85    ErrorOut5(0   != temp, "Cannot change memory size");
86
87    return (temp);
88}
89
90void Cfree(char *block)
91{
92    if (block)
93    {
94        /* if(cfree(block) == 0)
95          Warning("Error in Cfree..."); */
96        free(block);
97    }
98    else
99        Warning("Error in Cfree, NULL block");
100    return;
101}
102
103
104static void ReadNA_Flat(char *filename, char *dataset) {
105    size_t j;
106    int jj, curelem=0, offset;
107    char buffer[GBUFSIZ];
108    char in_line[GBUFSIZ];
109
110    NA_Sequence *this_elem;
111    NA_Alignment *data;
112
113    FILE *file;
114
115    data = (NA_Alignment*)dataset;
116
117    file = fopen(filename, "r");
118    if (file == NULL)
119    {
120        fprintf(stderr, "Cannot open %s.\n", filename);
121        return;
122    }
123    for (; fgets(in_line, GBUFSIZ, file) != 0;)
124    {
125        if (in_line[0] == '#' ||
126            in_line[0] == '%' ||
127            in_line[0] == '"' ||
128            in_line[0] == '@')
129        {
130            offset = 0;
131            for (j=0; j<strlen(in_line); j++)
132            {
133                if (in_line[j] == '(')
134                {
135                    sscanf((char*)
136                           &(in_line[j+1]), "%d", &offset);
137                    in_line[j] = '\0';
138                }
139            }
140
141            curelem = data->numelements++;
142            if (curelem == 0)
143            {
144                data->element=(NA_Sequence*)
145                    Calloc(5, sizeof(NA_Sequence));
146                data->maxnumelements = 5;
147            }
148            else if (curelem==data->maxnumelements)
149            {
150                (data->maxnumelements) *= 2;
151                data->element=
152                    (NA_Sequence*)Realloc((char*)data->element
153                                          , data->maxnumelements*sizeof(NA_Sequence));
154            }
155
156            InitNASeq(&(data->element[curelem]),
157                      in_line[0] == '#' ? DNA :
158                      in_line[0] == '%' ? PROTEIN :
159                      in_line[0] == '"' ? TEXT :
160                      in_line[0] == '@' ? MASK : TEXT);
161            this_elem = &(data->element[curelem]);
162            if (in_line[strlen(in_line)-1] == '\n')
163                in_line[strlen(in_line)-1] = '\0';
164            strncpy_terminate(this_elem->short_name, in_line+1, SIZE_SHORT_NAME);
165            this_elem->offset = offset;
166        }
167        else if (in_line[0] != '\n')
168        {
169            size_t strl = strlen(in_line);
170            for (j=0, jj=0; j<strl; j++)
171                if (in_line[j] != ' ' && in_line[j] != '\n' &&
172                   in_line[j] != '\t')
173                    buffer[jj++] = in_line[j];
174
175            if (data->element[curelem].rmatrix)
176                Ascii2NA(buffer, jj, data->element[curelem].rmatrix);
177            AppendNA((NA_Base*)buffer, jj, &(data->element[curelem]));
178        }
179    }
180    fclose(file);
181
182    for (j=0; j<data->numelements; j++)
183        data->maxlen = MAX(data->maxlen, data->element[j].seqlen +
184                           data->element[j].offset);
185
186    for (j=0; j<data->numelements; j++)
187        if (data->element[j].seqlen==0)
188            data->element[j].protect =
189                PROT_BASE_CHANGES + PROT_GREY_SPACE+
190                PROT_WHITE_SPACE + PROT_TRANSLATION;
191
192    NormalizeOffset(data);
193    Regroup(data);
194    return;
195}
196
197/*
198  LoadFile():
199  Load the given filename into the given dataset.  Handle any
200  type conversion needed to get the data into the specified data type.
201  This routine is used in situations where the format and datatype is known.
202
203  Copyright (c) 1989-1990, University of Illinois board of trustees.  All
204  rights reserved.  Written by Steven Smith at the Center for Prokaryote Genome
205  Analysis.  Design and implementation guidance by Dr. Gary Olsen and Dr.
206  Carl Woese.
207
208  Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
209  All rights reserved.
210*/
211
212static void LoadFile(char *filename, NA_Alignment *dataset, int type, int format)
213{
214
215    if (DataType != type)
216        fprintf(stderr, "Warning, datatypes do not match.\n");
217    /*
218      Handle the overwrite/create/merge dialog here.
219    */
220    switch (format)
221    {
222        case NA_FLAT:
223            ReadNA_Flat(filename, (char*)dataset);
224            ((NA_Alignment*)dataset)->format = GDE;
225            break;
226
227        case GENBANK:
228            ReadGen(filename, dataset);
229            ((NA_Alignment*)dataset)->format = GENBANK;
230            break;
231
232        case ARBDB:
233            ReadArbdb_plain(filename, dataset, type);
234            ((NA_Alignment*)dataset)->format = ARBDB;
235            break;
236
237        case GDE:
238            ReadGDE(filename, dataset);
239            ((NA_Alignment*)dataset)->format = GDE;
240            break;
241        case COLORMASK:
242            ReadCMask(filename);
243
244        default:
245            break;
246    }
247    return;
248}
249
250static int FindType(char *name, int *dtype, int *ftype)
251{
252    FILE *file;
253    char in_line[GBUFSIZ];
254
255    file = fopen(name, "r");
256    *dtype=0;
257    *ftype=0;
258
259    int result = 1;
260    if (file) {
261        /*   Is this a flat file?
262         *   Get the first non blank line, see if a type marker shows up.
263         */
264        if (fgets(in_line, GBUFSIZ, file)) {
265            for (; strlen(in_line)<2 && fgets(in_line, GBUFSIZ, file) != NULL;) ;
266
267            if (in_line[0] == '#' || in_line[0] == '%' ||
268                in_line[0]  == '"' || in_line[0] == '@')
269            {
270                *dtype=NASEQ_ALIGN;
271                *ftype=NA_FLAT;
272                result = 0;
273            }
274            else { // try genbank
275                fclose(file);
276                file = fopen(name, "r");
277                *dtype=0;
278                *ftype=0;
279
280                if (file) {
281                    for (; fgets(in_line, GBUFSIZ, file) != NULL;) {
282                        if (Find(in_line, "LOCUS"))
283                        {
284                            *dtype = NASEQ_ALIGN;
285                            *ftype = GENBANK;
286                            break;
287                        }
288                        else if (Find(in_line, "sequence")) { // try GDE
289                            *dtype = NASEQ_ALIGN;
290                            *ftype = GDE;
291                            break;
292                        }
293                        else if (Find(in_line, "start:"))
294                        {
295                            *dtype = NASEQ_ALIGN;
296                            *ftype = COLORMASK;
297                            break;
298                        }
299                    }
300                    result = 0;
301                }
302            }
303        }
304        fclose(file);
305    }
306
307    return result;
308}
309
310void LoadData(char *filen) {
311    /* LoadData():
312     * Load a data set from the command line argument.
313     *
314     * Copyright (c) 1989, University of Illinois board of trustees.  All rights
315     * reserved.  Written by Steven Smith at the Center for Prokaryote Genome
316     * Analysis.  Design and implementation guidance by Dr. Gary Olsen and Dr.
317     * Carl Woese.
318     * Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
319     * All rights reserved.
320     */
321
322    FILE         *file;
323    NA_Alignment *DataNaAln;
324    char          temp[1024];
325
326    // Get file name, determine the file type, and away we go..
327    if (Find2(filen, "gde") != 0)
328        strcpy(FileName, filen);
329
330    if (strstr(filen, ".arb") || strchr(filen, ':')) {  // ARBDB TYPE
331        if (DataSet == NULL) {
332            DataSet = (NA_Alignment *) Calloc(1,
333                                              sizeof(NA_Alignment));
334            DataNaAln = (NA_Alignment *) DataSet;
335            DataSet->rel_offset = 0;
336        }
337        else {
338            DataNaAln = (NA_Alignment *) DataSet;
339        }
340        DataType = NASEQ_ALIGN;
341        FileFormat = ARBDB;
342        LoadFile(filen, DataNaAln,
343                 DataType, FileFormat);
344
345        sprintf(temp, "Remote ARBDB access (%s)", filen);
346        return;
347    }
348
349
350    if ((file=fopen(filen, "r"))!=0)
351    {
352        FindType(filen, &DataType, &FileFormat);
353        switch (DataType)
354        {
355            case NASEQ_ALIGN:
356                if (DataSet == NULL)
357                {
358                    DataSet = (NA_Alignment*)Calloc(1,
359                                                    sizeof(NA_Alignment));
360                    DataNaAln = (NA_Alignment*)DataSet;
361                    DataSet->rel_offset = 0;
362                }
363                else {
364                    DataNaAln = (NA_Alignment*)DataSet;
365                }
366
367                LoadFile(filen, DataNaAln,
368                         DataType, FileFormat);
369
370                break;
371            default:
372                aw_message(GBS_global_string("Internal error: unknown file type of file %s", filen));
373                break;
374        }
375        fclose(file);
376    }
377    sprintf(temp, "Genetic Data Environment 2.2 (%s)", FileName);
378    return;
379}
380
381
382void AppendNA(NA_Base *buffer, int len, NA_Sequence *seq)
383{
384    int curlen=0, j;
385    if (seq->seqlen+len >= seq->seqmaxlen)
386    {
387        if (seq->seqlen>0)
388            seq->sequence = (NA_Base*)Realloc((char*)seq->sequence,
389                                              (seq->seqlen + len+GBUFSIZ) * sizeof(NA_Base));
390        else
391            seq->sequence = (NA_Base*)Calloc(1, (seq->seqlen +
392                                                len+GBUFSIZ) * sizeof(NA_Base));
393        seq->seqmaxlen = seq->seqlen + len+GBUFSIZ;
394    }
395    // seqlen is the length, and the index of the next free base
396    curlen = seq->seqlen + seq->offset;
397    for (j=0; j<len; j++)
398        putelem(seq, j+curlen, buffer[j]);
399
400    seq->seqlen += len;
401    return;
402}
403
404void Ascii2NA(char *buffer, int len, int matrix[16])
405{
406    // if the translation matrix exists, use it to encode the buffer.
407    int i;
408    if (matrix != NULL) {
409        for (i=0; i<len; i++) {
410            buffer[i] = matrix[(unsigned char)buffer[i]];
411        }
412    }
413    return;
414}
415
416int WriteNA_Flat(NA_Alignment *aln, char *filename, int method, int maskable)
417{
418    size_t j;
419    int kk, mask = -1, k, offset;
420    char offset_str[100], buf[100];
421    NA_Sequence *seqs;
422    FILE *file;
423    if (aln == NULL)
424        return (1);
425    if (aln->numelements == 0)
426        return (1);
427    seqs = aln->element;
428
429    file = fopen(filename, "w");
430    if (file == NULL)
431    {
432        Warning("Cannot open file for output");
433        return (1);
434    }
435    if (maskable && (method != SELECT_REGION))
436    {
437        for (j=0; j<aln->numelements; j++)
438            if (seqs[j].elementtype == MASK &&
439               seqs[j].selected)
440                mask = j;
441    }
442    /* Removed by OLIVER
443       for(j=0;j<aln->numelements;j++)
444       {
445       SeqNorm(&(seqs[j]));
446       }
447    */
448
449    for (j=0; j<aln->numelements; j++)
450    {
451        if (method != SELECT_REGION) {
452            offset = seqs[j].offset;
453        }
454        else {
455            for (offset=seqs[j].offset; aln->selection_mask[offset] == '0'; offset++) ;
456        }
457
458        if (offset+aln->rel_offset != 0)
459            sprintf(offset_str, "(%d)", offset+aln->rel_offset);
460        else
461            offset_str[0] = '\0';
462
463        if ((((int)j!=mask) && (seqs[j].selected) && method != SELECT_REGION)
464           || (method == SELECT_REGION && seqs[j].subselected)
465           || method == ALL)
466        {
467            fprintf(file, "%c%s%s\n",
468                    seqs[j].elementtype == DNA ? '#' :
469                    seqs[j].elementtype == RNA ? '#' :
470                    seqs[j].elementtype == PROTEIN ? '%' :
471                    seqs[j].elementtype == TEXT ? '"' :
472                    seqs[j].elementtype == MASK ? '@' : '"',
473                    seqs[j].short_name,
474                    (offset+aln->rel_offset  == 0) ? "" : offset_str);
475            if (seqs[j].tmatrix)
476            {
477                if (mask == -1)
478                    for (k=0, kk=0; kk<seqs[j].seqlen; kk++)
479                    {
480                        if ((k)%60 == 0 && k>0)
481                        {
482                            buf[60] = '\0';
483                            fputs(buf, file);
484                            putc('\n', file);
485                        }
486                        if (method == SELECT_REGION)
487                        {
488                            if (aln->selection_mask[kk+offset]=='1')
489                            {
490                                buf[k%60] = ((char)seqs[j].tmatrix[
491                                                                  (int)getelem(&(seqs[j]), kk+offset)]);
492                                k++;
493                            }
494                        }
495                        else
496                        {
497                            buf[k%60] = ((char)seqs[j].tmatrix[
498                                                              (int)getelem(&(seqs[j]), kk+offset)]);
499                            k++;
500                        }
501                    }
502                else
503                    for (k=0, kk=0; kk<seqs[j].seqlen; kk++)
504                    {
505                        if (getelem(&(seqs[mask]), kk+seqs[mask].offset) != '0'
506                           && (getelem(&(seqs[mask]), kk+seqs[mask].offset)
507                               != '-'))
508                        {
509                            if ((k++)%60 == 0 && k>1)
510                            {
511                                buf[60] = '\0';
512                                fputs(buf, file);
513                                putc('\n', file);
514                            }
515                            buf[k%60] = ((char)seqs[j].tmatrix
516                                         [getelem(&(seqs[j]), kk+offset)]);
517                        }
518                    }
519            }
520            else
521            {
522                if (mask == -1)
523                    for (k=0, kk=0; kk<seqs[j].seqlen; kk++)
524                    {
525                        if ((k)%60 == 0 && k>0)
526                        {
527                            buf[60] = '\0';
528                            fputs(buf, file);
529                            putc('\n', file);
530                        }
531                        if (method == SELECT_REGION)
532                        {
533                            if (aln->selection_mask[kk+offset]=='1')
534                            {
535                                buf[k%60] = (getelem(&(seqs[j]), kk+offset));
536                                k++;
537                            }
538                        }
539                        else
540                        {
541                            buf[k%60] = (getelem(&(seqs[j]), kk+offset));
542                            k++;
543                        }
544                    }
545                else
546                    for (k=0, kk=0; kk<seqs[j].seqlen; kk++)
547                    {
548                        if (getelem(&(seqs[mask]), kk+offset) == '1')
549                        {
550                            if ((k++)%60 == 0 && k>1)
551                            {
552                                buf[60] = '\0';
553                                fputs(buf, file);
554                                putc('\n', file);
555                            }
556                            buf[k%60] = ((char)getelem(&(seqs[j]),
557                                                      kk+offset));
558                        }
559                    }
560            }
561            buf[(k%60)>0 ? (k%60) : 60] = '\0';
562            fputs(buf, file);
563            putc('\n', file);
564        }
565    }
566    fclose(file);
567    return (0);
568}
569
570
571void Warning(const char *s) {
572    aw_message(s);
573}
574
575
576void InitNASeq(NA_Sequence *seq, int type) {
577    SetTime(&(seq->t_stamp.origin));
578    SetTime(&(seq->t_stamp.modify));
579    strncpy_terminate(seq->id, uniqueID(), SIZE_ID);
580    seq->seq_name[0] = '\0';
581    seq->barcode[0] = '\0';
582    seq->contig[0] = '\0';
583    seq->membrane[0] = '\0';
584    seq->authority[0] = '\0';
585    seq->short_name[0] = '\0';
586    seq->sequence = NULL;
587    seq->offset = 0;
588    seq->baggage = NULL;
589    seq->baggage_len = 0;
590    seq->baggage_maxlen = 0;
591    seq->comments = NULL;
592    seq->comments_len = 0;
593    seq->comments_maxlen = 0;
594    seq->description[0] = '\0';
595    seq->mask = NULL;
596    seq->seqlen = 0;
597    seq->seqmaxlen = 0;
598    seq->protect = PROT_WHITE_SPACE + PROT_TRANSLATION;
599#ifdef HGL
600    seq->attr = 0;
601#else
602    seq->attr = IS_5_TO_3 + IS_PRIMARY;
603#endif
604    seq->elementtype = type;
605    seq->groupid = 0;
606    seq->groupb = NULL;
607    seq->groupf = NULL;
608    seq->cmask = NULL;
609    seq->selected = 0;
610    seq->subselected = 0;
611
612    switch (type)
613    {
614        case DNA:
615            seq->tmatrix = Default_DNA_Trans;
616            seq->rmatrix = Default_NA_RTrans;
617            seq->col_lut = Default_NAColor_LKUP;
618            break;
619        case RNA:
620            seq->tmatrix = Default_RNA_Trans;
621            seq->rmatrix = Default_NA_RTrans;
622            seq->col_lut = Default_NAColor_LKUP;
623            break;
624        case PROTEIN:
625            seq->tmatrix = NULL;
626            seq->rmatrix = NULL;
627            seq->col_lut = Default_PROColor_LKUP;
628            break;
629        case MASK:
630        case TEXT:
631        default:
632            seq->tmatrix = NULL;
633            seq->rmatrix = NULL;
634            seq->col_lut = NULL;
635            break;
636    }
637    return;
638}
639
640
641void ReadCMask(const char *filename)
642{
643
644    char in_line[GBUFSIZ];
645    char head[GBUFSIZ];
646    char curname[GBUFSIZ];
647    char temp[GBUFSIZ];
648    bool IGNORE_DASH = false;
649    int  offset;
650
651    NA_Alignment *aln;
652
653    size_t  j;
654    size_t  curlen = 0;
655    int    *colors = 0, jj, indx = 0;
656    FILE   *file;
657
658    if (DataSet == NULL) return;
659
660    aln = (NA_Alignment*)DataSet;
661
662    curname[0] = '\0';
663    file = fopen(filename, "r");
664    if (file == NULL)
665    {
666        Warning("File not found");
667        Warning(filename);
668        return;
669    }
670
671    for (; fgets(in_line, GBUFSIZ, file) != 0;)
672    {
673        if (Find(in_line, "offset:"))
674        {
675            crop(in_line, head, temp);
676            sscanf(temp, "%d", &(aln->cmask_offset));
677        }
678        else if (Find(in_line, "nodash:"))
679            IGNORE_DASH = true;
680        else if (Find(in_line, "dash:"))
681            IGNORE_DASH = true;
682        else if (Find(in_line, "name:"))
683        {
684            crop(in_line, head, curname);
685            curname[strlen(curname)-1] = '\0';
686            for (j=0; j<strlen(curname); j++)
687                if (curname[j] == '(')
688                    curname[j] = '\0';
689        }
690        else if (Find(in_line, "length:"))
691        {
692            crop(in_line, head, temp);
693            sscanf(temp, "%zu", &curlen);
694        }
695        else if (Find(in_line, "start:"))
696        {
697            indx = -1;
698            if (curlen == 0)
699            {
700                Warning("illegal format in colormask");
701                fclose(file);
702                return;
703            }
704            if (strlen(curname) != 0)
705            {
706                indx = -1;
707                for (j=0; j<aln->numelements; j++)
708                    if (Find(aln->element[j].short_name, curname)
709                       || Find(aln->element[j].id, curname))
710                    {
711                        if (aln->element[j].cmask != NULL)
712                            Cfree((char*)aln -> element[j].cmask);
713                        colors=(int*)Calloc(aln->element[j]
714                                            .seqmaxlen+1+aln->element[j].offset
715                                            , sizeof(int));
716                        aln->element[j].cmask = colors;
717                        indx = j;
718                        j = aln->numelements;
719                    }
720                if (indx == -1)
721                    colors=NULL;
722            }
723            else
724            {
725                if (aln->cmask != NULL) Cfree((char*)aln->cmask);
726                colors=(int*)Calloc(curlen, sizeof(int));
727                aln->cmask = colors;
728                aln->cmask_len = curlen;
729                for (j=0; j<curlen; j++)
730                    colors[j] = 12;
731            }
732
733            if (IGNORE_DASH && (indx != -1))
734            {
735                for (jj=0, j=0; (j<curlen) &&
736                        (jj<aln->element[indx].seqlen); j++, jj++)
737                {
738                    offset = aln->element[indx].offset;
739                    if (fgets(in_line, GBUFSIZ, file)==NULL)
740                    {
741                        Warning("illegal format in colormask");
742                        fclose(file);
743                        return;
744                    }
745                    /*  Fixed so that the keyword nodash causes the colormask to be mapped
746                     *  to the sequence, not the alignment.
747                     *
748                     *  The allocated space is equal the seqlen of the matched sequence.
749                     */
750                    if (aln->element[indx].tmatrix)
751                        for (; (getelem(&(aln->element[indx]), jj
752                                      +offset)
753                              ==(aln->element[indx].tmatrix['-'])
754                              || (getelem(&(aln->element[indx]), jj
755                                          +offset)
756                                  ==aln->element[indx].tmatrix['~']))
757                                && jj < aln->element[indx].seqlen;)
758                            colors[jj++] = 12;
759                    else
760                        for (; getelem(&(aln->element[indx]), jj
761                                     +offset)
762                                =='-' && jj < aln->element[indx].seqlen;)
763                            colors[jj++] = 12;
764
765                    sscanf(in_line, "%d", &(colors[jj]));
766                }
767            }
768            else if ((indx == -1) && (strlen(curname) != 0)) {
769                for (j=0; j<curlen; j++) {
770                    char *read = fgets(in_line, GBUFSIZ, file);
771                    if (!read) {
772                        Warning("Unexepected end of file");
773                        return;
774                    }
775                }
776            }
777            else
778                for (j=0; j<curlen; j++)
779                {
780                    if (fgets(in_line, GBUFSIZ, file)==NULL)
781                    {
782                        Warning("illegal format in colormask");
783                        return;
784                    }
785                    sscanf(in_line, "%d", &(colors[j]));
786                }
787            IGNORE_DASH = false;
788            curname[0] = '\0';
789        }
790
791    }
792    fclose(file);
793    return;
794}
795
796
797int WriteStatus(NA_Alignment *aln, char *filename) {
798    NA_Sequence *this_seq;
799    int j;
800    FILE *file;
801    filename=0;
802
803    if (DataSet == NULL)
804        return (1);
805
806    gde_assert(filename != NULL);
807    file = fopen(filename, "w");
808    if (file == NULL)
809    {
810        Warning("Cannot open status file.");
811        return (1);
812    }
813    fprintf(file, "File_format: %s\n", FileFormat==GENBANK ? "genbank" : "flat");
814
815    this_seq = &(aln->element[1]); // Nadd->cursor !?
816    if (this_seq->id[0]) fprintf(file, "sequence-ID %s\n", this_seq->id);
817    fprintf(file, "Column: %d\nPos:%d\n", 1, 1); // NAdd->cursor_x,NAdd->position
818    switch (this_seq->elementtype)
819    {
820        case DNA:
821        case RNA:
822            fprintf(file, "#%s\n",
823                    this_seq->short_name);
824            break;
825        case PROTEIN:
826            fprintf(file, "%%%s\n",
827                    this_seq->short_name);
828            break;
829        case MASK:
830            fprintf(file, "@%s\n",
831                    this_seq->short_name);
832            break;
833        case TEXT:
834            fprintf(file, "%c%s\n", '"',
835                    this_seq->short_name);
836            break;
837        default:
838            break;
839    }
840    if (this_seq->tmatrix)
841        for (j=0; j<this_seq->seqlen; j++)
842            putc(this_seq->tmatrix[getelem(this_seq, j)], file);
843    else
844        for (j=0; j<this_seq->seqlen; j++)
845            putc(getelem(this_seq, j), file);
846
847    fclose(file);
848    return (0);
849}
850
851
852void NormalizeOffset(NA_Alignment *aln)
853{
854    size_t j;
855    int offset = INT_MAX;
856
857    for (j=0; j<aln->numelements; j++)
858        offset = MIN(offset, aln->element[j].offset);
859
860    for (j=0; j<aln->numelements; j++)
861        aln->element[j].offset -= offset;
862
863    aln->maxlen = INT_MIN;
864    for (j=0; j<aln->numelements; j++)
865        aln->maxlen = MAX(aln->element[j].seqlen+aln->element[j].offset,
866                          aln->maxlen);
867
868    gde_assert(aln->maxlen >= 0);
869
870    aln->rel_offset += offset;
871
872    if (aln->numelements == 0)
873        aln->rel_offset = 0;
874
875    return;
876}
877
878int WriteCMask(NA_Alignment *aln, char *filename, int method, int maskable)
879{
880    size_t j;
881    int kk, mask = -1, k, offset;
882    char offset_str[100];
883    int *buf;
884    NA_Sequence *seqs;
885    FILE *file;
886    if (aln == NULL)
887        return (1);
888
889    if (aln->numelements == 0)
890        return (1);
891    seqs = aln->element;
892
893    file = fopen(filename, "w");
894    if (file == NULL)
895    {
896        Warning("Cannot open file for output");
897        return (1);
898    }
899    if (maskable && (method != SELECT_REGION))
900    {
901        for (j=0; j<aln->numelements; j++)
902            if (seqs[j].elementtype == MASK &&
903               seqs[j].selected)
904                mask = j;
905    }
906    for (j=0; j<aln->numelements; j++)
907    {
908        SeqNorm(&(seqs[j]));
909    }
910
911    for (j=0; j<aln->numelements; j++)
912    {
913        if (method != SELECT_REGION) {
914            offset = seqs[j].offset;
915        }
916        else {
917            for (offset=seqs[j].offset; aln->selection_mask[offset] == '0'; offset++) ;
918        }
919
920        if (offset+aln->rel_offset != 0) {
921            sprintf(offset_str, "(%d)", offset+aln->rel_offset);
922        }
923        else {
924            offset_str[0] = '\0';
925        }
926
927        if ((((int)j!=mask) && (seqs[j].selected) && method != SELECT_REGION)
928           || (method == SELECT_REGION && seqs[j].subselected)
929           || method == ALL)
930        {
931            fprintf(file, "%c%s%s\n",
932                    seqs[j].elementtype == DNA ? '#' :
933                    seqs[j].elementtype == RNA ? '#' :
934                    seqs[j].elementtype == PROTEIN ? '%' :
935                    seqs[j].elementtype == TEXT ? '"' :
936                    seqs[j].elementtype == MASK ? '@' : '"',
937                    seqs[j].short_name,
938                    (offset+aln->rel_offset  == 0) ? "" : offset_str);
939
940            if (seqs[j].cmask != NULL)
941            {
942
943                buf = (int*) Calloc(seqs[j].seqlen, sizeof(int));
944
945                if (mask == -1)
946                {
947                    for (k=0, kk=0; kk<seqs[j].seqlen; kk++)
948                    {
949                        if (method == SELECT_REGION)
950                        {
951                            if (aln->selection_mask[kk+offset]=='1')
952                                buf[k++] = (getcmask(&(seqs[j]), kk+offset));
953                        }
954
955                        else
956                            buf[k++] = (getcmask(&(seqs[j]), kk+offset));
957                    }
958                }
959                else
960                {
961                    for (k=0, kk=0; kk<seqs[j].seqlen; kk++)
962                        if (getelem(&(seqs[mask]), kk+offset) == '1')
963                            buf[k++] = (getcmask(&(seqs[j]), kk+offset));
964                    // @@@ Looks like k might be one behind?
965                }
966                fprintf(file, "name:%s\noffset:%d\nlength:%d\nstart:\n",
967                        seqs[j].short_name, seqs[j].offset, k);
968
969                for (kk = 0; kk < k; kk++)
970                    fprintf(file, "%d\n", buf[kk]);
971
972                Cfree((char*)buf);
973            }
974        }
975    }
976    fclose(file);
977    return (0);
978}
Note: See TracBrowser for help on using the browser.