source: tags/arb-6.0/ARB_GDE/GDE_FileIO.cxx

Last change on this file was 11886, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.1 KB
Line 
1#include "GDE_proto.h"
2#include <limits.h>
3#include <aw_msg.hxx>
4#include <algorithm>
5
6void Regroup(NA_Alignment *alignment)
7{
8    size_t j;
9    size_t group;
10    int last;
11
12    for (j=0; j<alignment->numelements; j++)
13    {
14        alignment->element[j].groupf = NULL;
15        alignment->element[j].groupb = NULL;
16    }
17
18    for (group = 1; group <= alignment->numgroups; group++)
19    {
20        last = -1;
21        for (j=0; j<alignment->numelements; j++)
22            if (alignment->element[j].groupid == group)
23            {
24                if (last != -1)
25                {
26                    alignment->element[j].groupb =
27                        &(alignment->element[last]);
28                    alignment->element[last].groupf =
29                        &(alignment->element[j]);
30                }
31                last = j;
32            }
33    }
34    return;
35}
36
37template <typename T>
38inline T* Terminate_If_OutOfMemory(T *allocated) {
39    if (!allocated) GBK_terminate("Out of memory");
40    return allocated;
41}
42
43char *Calloc(int count, int size) {
44    // More robust memory management routines
45    size *= count;
46    char *temp  = (char *)malloc(size);
47    memset(Terminate_If_OutOfMemory(temp), 0, size);
48    return temp;
49}
50
51char *Realloc(char *block, int size) {
52    return Terminate_If_OutOfMemory((char*)realloc(block, size));
53}
54
55void Cfree(char *block)
56{
57    if (block)
58    {
59        /* if(cfree(block) == 0)
60          Warning("Error in Cfree..."); */
61        free(block);
62    }
63    else
64        Warning("Error in Cfree, NULL block");
65    return;
66}
67
68static void ReadNA_Flat(char *filename, char *dataset) {
69    size_t j;
70    int jj, curelem=0, offset;
71    char buffer[GBUFSIZ];
72    char in_line[GBUFSIZ];
73
74    NA_Sequence *this_elem;
75    NA_Alignment *data;
76
77    FILE *file;
78
79    data = (NA_Alignment*)dataset;
80
81    file = fopen(filename, "r");
82    if (file == NULL)
83    {
84        fprintf(stderr, "Cannot open %s.\n", filename);
85        return;
86    }
87    for (; fgets(in_line, GBUFSIZ, file) != 0;)
88    {
89        if (in_line[0] == '#' ||
90            in_line[0] == '%' ||
91            in_line[0] == '"' ||
92            in_line[0] == '@')
93        {
94            offset = 0;
95            for (j=0; j<strlen(in_line); j++)
96            {
97                if (in_line[j] == '(')
98                {
99                    sscanf((char*)
100                           &(in_line[j+1]), "%d", &offset);
101                    in_line[j] = '\0';
102                }
103            }
104
105            curelem = data->numelements++;
106            if (curelem == 0)
107            {
108                data->element=(NA_Sequence*)
109                    Calloc(5, sizeof(NA_Sequence));
110                data->maxnumelements = 5;
111            }
112            else if (curelem==data->maxnumelements)
113            {
114                (data->maxnumelements) *= 2;
115                data->element=
116                    (NA_Sequence*)Realloc((char*)data->element
117                                          , data->maxnumelements*sizeof(NA_Sequence));
118            }
119
120            InitNASeq(&(data->element[curelem]),
121                      in_line[0] == '#' ? DNA :
122                      in_line[0] == '%' ? PROTEIN :
123                      in_line[0] == '"' ? TEXT :
124                      in_line[0] == '@' ? MASK : TEXT);
125            this_elem = &(data->element[curelem]);
126            if (in_line[strlen(in_line)-1] == '\n')
127                in_line[strlen(in_line)-1] = '\0';
128            strncpy_terminate(this_elem->short_name, in_line+1, SIZE_SHORT_NAME);
129            this_elem->offset = offset;
130        }
131        else if (in_line[0] != '\n')
132        {
133            size_t strl = strlen(in_line);
134            for (j=0, jj=0; j<strl; j++)
135                if (in_line[j] != ' ' && in_line[j] != '\n' &&
136                   in_line[j] != '\t')
137                    buffer[jj++] = in_line[j];
138
139            if (data->element[curelem].rmatrix)
140                Ascii2NA(buffer, jj, data->element[curelem].rmatrix);
141            AppendNA((NA_Base*)buffer, jj, &(data->element[curelem]));
142        }
143    }
144    fclose(file);
145
146    for (j=0; j<data->numelements; j++)
147        data->maxlen = std::max(data->maxlen, data->element[j].seqlen +
148                                data->element[j].offset);
149
150    for (j=0; j<data->numelements; j++)
151        if (data->element[j].seqlen==0)
152            data->element[j].protect =
153                PROT_BASE_CHANGES + PROT_GREY_SPACE+
154                PROT_WHITE_SPACE + PROT_TRANSLATION;
155
156    NormalizeOffset(data);
157    Regroup(data);
158    return;
159}
160
161/*
162  LoadFile():
163  Load the given filename into the given dataset.  Handle any
164  type conversion needed to get the data into the specified data type.
165  This routine is used in situations where the format and datatype is known.
166
167  Copyright (c) 1989-1990, University of Illinois board of trustees.  All
168  rights reserved.  Written by Steven Smith at the Center for Prokaryote Genome
169  Analysis.  Design and implementation guidance by Dr. Gary Olsen and Dr.
170  Carl Woese.
171
172  Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
173  All rights reserved.
174*/
175
176static GB_ERROR LoadFile(char *filename, NA_Alignment *dataset, int type, int format) {
177    GB_ERROR error = NULL;
178    if (DataType != type)
179        fprintf(stderr, "Warning, datatypes do not match.\n");
180    /*
181      Handle the overwrite/create/merge dialog here.
182    */
183    switch (format)
184    {
185        case NA_FLAT:
186            ReadNA_Flat(filename, (char*)dataset);
187            ((NA_Alignment*)dataset)->format = GDE;
188            break;
189
190        case GENBANK:
191            error                            = ReadGen(filename, dataset);
192            ((NA_Alignment*)dataset)->format = GENBANK;
193            break;
194
195        case GDE:
196            gde_assert(0); // should no longer occur
197            break;
198
199        default:
200            break;
201    }
202    return error;
203}
204
205static int FindType(char *name, int *dtype, int *ftype) {
206    FILE *file = fopen(name, "r");
207
208    *dtype = 0;
209    *ftype = 0;
210
211    int result = 1;
212    if (file) {
213        /*   Is this a flat file?
214         *   Get the first non blank line, see if a type marker shows up.
215         */
216        char in_line[GBUFSIZ];
217        if (fgets(in_line, GBUFSIZ, file)) {
218            for (; strlen(in_line)<2 && fgets(in_line, GBUFSIZ, file) != NULL;) ;
219
220            if (in_line[0] == '#' || in_line[0] == '%' ||
221                in_line[0]  == '"' || in_line[0] == '@')
222            {
223                *dtype=NASEQ_ALIGN;
224                *ftype=NA_FLAT;
225                result = 0;
226            }
227            else { // try genbank
228                fclose(file);
229                file = fopen(name, "r");
230                *dtype=0;
231                *ftype=0;
232
233                if (file) {
234                    for (; fgets(in_line, GBUFSIZ, file) != NULL;) {
235                        if (Find(in_line, "LOCUS"))
236                        {
237                            *dtype = NASEQ_ALIGN;
238                            *ftype = GENBANK;
239                            break;
240                        }
241                        else if (Find(in_line, "sequence")) { // try GDE
242                            *dtype = NASEQ_ALIGN;
243                            *ftype = GDE;
244                            break;
245                        }
246                    }
247                    result = 0;
248                }
249            }
250        }
251        fclose(file);
252    }
253
254    return result;
255}
256
257void LoadData(char *filen) {
258    /* LoadData():
259     * Load a data set from the command line argument.
260     *
261     * Copyright (c) 1989, University of Illinois board of trustees.  All rights
262     * reserved.  Written by Steven Smith at the Center for Prokaryote Genome
263     * Analysis.  Design and implementation guidance by Dr. Gary Olsen and Dr.
264     * Carl Woese.
265     * Copyright (c) 1990,1991,1992 Steven Smith at the Harvard Genome Laboratory.
266     * All rights reserved.
267     */
268
269    FILE         *file;
270    NA_Alignment *DataNaAln;
271
272    // Get file name, determine the file type, and away we go..
273    if (Find2(filen, "gde") != 0)
274        strcpy(FileName, filen);
275
276    if ((file=fopen(filen, "r"))!=0)
277    {
278        FindType(filen, &DataType, &FileFormat);
279        switch (DataType)
280        {
281            case NASEQ_ALIGN: {
282                if (DataSet == NULL)
283                {
284                    DataSet = (NA_Alignment*)Calloc(1, sizeof(NA_Alignment));
285                    DataNaAln = (NA_Alignment*)DataSet;
286                    DataSet->rel_offset = 0;
287                }
288                else {
289                    DataNaAln = (NA_Alignment*)DataSet;
290                }
291
292                GB_ERROR error = LoadFile(filen, DataNaAln, DataType, FileFormat);
293                if (error) aw_message(error);
294
295                break;
296            }
297            default:
298                aw_message(GBS_global_string("Internal error: unknown file type of file %s", filen));
299                break;
300        }
301        fclose(file);
302    }
303}
304
305void AppendNA(NA_Base *buffer, int len, NA_Sequence *seq)
306{
307    int curlen=0, j;
308    if (seq->seqlen+len >= seq->seqmaxlen)
309    {
310        if (seq->seqlen>0)
311            seq->sequence = (NA_Base*)Realloc((char*)seq->sequence,
312                                              (seq->seqlen + len+GBUFSIZ) * sizeof(NA_Base));
313        else
314            seq->sequence = (NA_Base*)Calloc(1, (seq->seqlen +
315                                                len+GBUFSIZ) * sizeof(NA_Base));
316        seq->seqmaxlen = seq->seqlen + len+GBUFSIZ;
317    }
318    // seqlen is the length, and the index of the next free base
319    curlen = seq->seqlen + seq->offset;
320    for (j=0; j<len; j++)
321        putelem(seq, j+curlen, buffer[j]);
322
323    seq->seqlen += len;
324    return;
325}
326
327void Ascii2NA(char *buffer, int len, int matrix[16]) {
328    // if the translation matrix exists, use it to encode the buffer.
329    if (matrix != NULL) {
330        for (int i=0; i<len; i++) {
331            buffer[i] = matrix[(unsigned char)buffer[i]];
332        }
333    }
334}
335
336int WriteNA_Flat(NA_Alignment *aln, char *filename, int method)
337{
338    size_t j;
339    int kk;
340    int k, offset;
341    char offset_str[100], buf[100];
342    NA_Sequence *seqs;
343    FILE *file;
344    if (aln == NULL)
345        return (1);
346    if (aln->numelements == 0)
347        return (1);
348    seqs = aln->element;
349
350    file = fopen(filename, "w");
351    if (file == NULL)
352    {
353        Warning("Cannot open file for output");
354        return (1);
355    }
356
357    for (j=0; j<aln->numelements; j++)
358    {
359        offset = seqs[j].offset;
360
361        if (offset+aln->rel_offset != 0)
362            sprintf(offset_str, "(%d)", offset+aln->rel_offset);
363        else
364            offset_str[0] = '\0';
365
366        if (method == ALL)
367        {
368            fprintf(file, "%c%s%s\n",
369                    seqs[j].elementtype == DNA ? '#' :
370                    seqs[j].elementtype == RNA ? '#' :
371                    seqs[j].elementtype == PROTEIN ? '%' :
372                    seqs[j].elementtype == TEXT ? '"' :
373                    seqs[j].elementtype == MASK ? '@' : '"',
374                    seqs[j].short_name,
375                    (offset+aln->rel_offset  == 0) ? "" : offset_str);
376            if (seqs[j].tmatrix)
377            {
378                for (k=0, kk=0; kk<seqs[j].seqlen; kk++)
379                {
380                    if ((k)%60 == 0 && k>0)
381                    {
382                        buf[60] = '\0';
383                        fputs(buf, file);
384                        putc('\n', file);
385                    }
386                    buf[k%60] = ((char)seqs[j].tmatrix[(int)getelem(&(seqs[j]), kk+offset)]);
387                    k++;
388                }
389            }
390            else
391            {
392                for (k=0, kk=0; kk<seqs[j].seqlen; kk++)
393                {
394                    if ((k)%60 == 0 && k>0)
395                    {
396                        buf[60] = '\0';
397                        fputs(buf, file);
398                        putc('\n', file);
399                    }
400                    buf[k%60] = (getelem(&(seqs[j]), kk+offset));
401                    k++;
402                }
403            }
404            buf[(k%60)>0 ? (k%60) : 60] = '\0';
405            fputs(buf, file);
406            putc('\n', file);
407        }
408    }
409    fclose(file);
410    return (0);
411}
412
413void Warning(const char *s) {
414    aw_message(s);
415}
416
417
418void InitNASeq(NA_Sequence *seq, int type) {
419    SetTime(&(seq->t_stamp.origin));
420    SetTime(&(seq->t_stamp.modify));
421    strncpy_terminate(seq->id, uniqueID(), SIZE_ID);
422    seq->seq_name[0] = '\0';
423    seq->barcode[0] = '\0';
424    seq->contig[0] = '\0';
425    seq->membrane[0] = '\0';
426    seq->authority[0] = '\0';
427    seq->short_name[0] = '\0';
428    seq->sequence = NULL;
429    seq->offset = 0;
430    seq->baggage = NULL;
431    seq->baggage_len = 0;
432    seq->baggage_maxlen = 0;
433    seq->comments = NULL;
434    seq->comments_len = 0;
435    seq->comments_maxlen = 0;
436    seq->description[0] = '\0';
437    seq->mask = NULL;
438    seq->seqlen = 0;
439    seq->seqmaxlen = 0;
440    seq->protect = PROT_WHITE_SPACE + PROT_TRANSLATION;
441#ifdef HGL
442    seq->attr = 0;
443#else
444    seq->attr = IS_5_TO_3 + IS_PRIMARY;
445#endif
446    seq->elementtype = type;
447    seq->groupid = 0;
448    seq->groupb = NULL;
449    seq->groupf = NULL;
450    seq->cmask = NULL;
451
452    switch (type)
453    {
454        case DNA:
455            seq->tmatrix = Default_DNA_Trans;
456            seq->rmatrix = Default_NA_RTrans;
457            seq->col_lut = Default_NAColor_LKUP;
458            break;
459        case RNA:
460            seq->tmatrix = Default_RNA_Trans;
461            seq->rmatrix = Default_NA_RTrans;
462            seq->col_lut = Default_NAColor_LKUP;
463            break;
464        case PROTEIN:
465            seq->tmatrix = NULL;
466            seq->rmatrix = NULL;
467            seq->col_lut = Default_PROColor_LKUP;
468            break;
469        case MASK:
470        case TEXT:
471        default:
472            seq->tmatrix = NULL;
473            seq->rmatrix = NULL;
474            seq->col_lut = NULL;
475            break;
476    }
477    return;
478}
479
480void NormalizeOffset(NA_Alignment *aln)
481{
482    size_t j;
483    int offset = INT_MAX;
484
485    for (j=0; j<aln->numelements; j++)
486        offset = std::min(offset, aln->element[j].offset);
487
488    for (j=0; j<aln->numelements; j++)
489        aln->element[j].offset -= offset;
490
491    aln->maxlen = INT_MIN;
492    for (j=0; j<aln->numelements; j++)
493        aln->maxlen = std::max(aln->element[j].seqlen+aln->element[j].offset,
494                          aln->maxlen);
495
496    gde_assert(aln->maxlen >= 0);
497
498    aln->rel_offset += offset;
499
500    if (aln->numelements == 0)
501        aln->rel_offset = 0;
502
503    return;
504}
Note: See TracBrowser for help on using the repository browser.