source: tags/ms_r16q2/ARB_GDE/GDE_FileIO.cxx

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