source: tags/ms_r16q3/ARB_GDE/GDE_FileIO.cxx

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