source: tags/ms_r18q1/ARB_GDE/GDE_FileIO.cxx

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