source: tags/ms_r16q2/ARB_GDE/GDE_arbdb_io.cxx

Last change on this file was 14473, checked in by westram, 9 years ago
  • remove unused AW_CL from GDE_init
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.6 KB
Line 
1#include "GDE_proto.h"
2
3#include <aw_msg.hxx>
4#include <arb_progress.h>
5#include <AW_rename.hxx>
6#include <AP_filter.hxx>
7#include <aw_awar_defs.hxx>
8
9#include <algorithm>
10
11// AISC_MKPT_PROMOTE:#ifndef GDE_EXTGLOB_H
12// AISC_MKPT_PROMOTE:#include "GDE_extglob.h"
13// AISC_MKPT_PROMOTE:#endif
14
15typedef unsigned int UINT;
16
17static int Arbdb_get_curelem(NA_Alignment& dataset)
18{
19    int curelem;
20    curelem = dataset.numelements++;
21    if (curelem == 0) {
22        dataset.element = (NA_Sequence *) Calloc(5, sizeof(NA_Sequence));
23        dataset.maxnumelements = 5;
24    }
25    else if (curelem == dataset.maxnumelements) {
26        dataset.maxnumelements *= 2;
27        dataset.element = (NA_Sequence *) Realloc((char *)dataset.element, dataset.maxnumelements * sizeof(NA_Sequence));
28    }
29    return curelem;
30}
31
32static void set_constant_fields(NA_Sequence *this_elem) {
33    this_elem->attr            = DEFAULT_X_ATTR;
34    this_elem->comments        = strdup("no comments");
35    this_elem->comments_maxlen = 1 + (this_elem->comments_len = strlen(this_elem->comments));
36    this_elem->rmatrix         = NULL;
37    this_elem->tmatrix         = NULL;
38    this_elem->col_lut         = Default_PROColor_LKUP;
39}
40
41static void AppendNA_and_free(NA_Sequence *this_elem, uchar *& sequfilt) {
42    AppendNA((NA_Base *)sequfilt, strlen((const char *)sequfilt), this_elem);
43    freenull(sequfilt);
44}
45
46__ATTR__USERESULT static int InsertDatainGDE(NA_Alignment&     dataset,
47                                             GBDATA          **the_species,
48                                             unsigned char   **the_names,
49                                             unsigned char   **the_sequences,
50                                             unsigned long     numberspecies,
51                                             unsigned long     maxalignlen,
52                                             const AP_filter  *filter,
53                                             GapCompression    compress,
54                                             bool              cutoff_stop_codon,
55                                             TypeInfo          typeinfo)
56{
57    GBDATA      *gb_species;
58    NA_Sequence *this_elem;
59    AP_filter   *allocatedFilter = 0;
60
61    gde_assert(contradicted(the_species, the_names));
62
63    if (filter==0) {
64        allocatedFilter = new AP_filter(maxalignlen);
65        filter          = allocatedFilter;
66    }
67    else {
68        size_t fl = filter->get_length();
69        if (fl < maxalignlen) {
70            aw_message("Warning: Your filter is shorter than the alignment len");
71            maxalignlen = fl;
72        }
73    }
74
75    GB_ERROR error = filter->is_invalid();
76    if (!error) {
77        size_t *seqlen=(size_t *)calloc((unsigned int)numberspecies, sizeof(size_t));
78        // sequences may have different length
79        {
80            unsigned long i;
81            for (i=0; i<numberspecies; i++) {
82                seqlen[i] = strlen((char *)the_sequences[i]);
83            }
84        }
85
86        if (cutoff_stop_codon) {
87            unsigned long i;
88            fputs("[CUTTING STOP CODONS]\n", stdout);
89            for (i=0; i<numberspecies; i++) {
90                uchar *seq        = the_sequences[i];
91                uchar *stop_codon = (uchar*)strchr((char*)seq, '*');
92                if (stop_codon) {
93                    long pos     = stop_codon-seq;
94                    long restlen = maxalignlen-pos;
95                    memset(stop_codon, '.', restlen);
96                }
97            }
98        }
99
100        // store (compressed) sequence data in array:
101        uchar             **sequfilt = (uchar**)calloc((unsigned int)numberspecies+1, sizeof(uchar*));
102        GB_alignment_type   alitype  = GBT_get_alignment_type(dataset.gb_main, dataset.alignment_name);
103
104        if (compress==COMPRESS_ALL) { // compress all gaps and filter positions
105            long          len = filter->get_filtered_length();
106            unsigned long i;
107
108            for (i=0; i<numberspecies; i++) {
109                sequfilt[i]   = (uchar*)calloc((unsigned int)len+1, sizeof(uchar));
110                long newcount = 0;
111                for (unsigned long col=0; (col<maxalignlen); col++) {
112                    char c = the_sequences[i][col];
113                    if (!c) break;
114                    if ((filter->use_position(col)) && (c!='-') && (c!='.')) {
115                        sequfilt[i][newcount++] = c;
116                    }
117                }
118            }
119        }
120        else {
121            if (compress==COMPRESS_VERTICAL_GAPS || // compress vertical gaps (and '.')
122                compress == COMPRESS_NONINFO_COLUMNS) // and additionally all columns containing no info (only N or X)
123            {
124                size_t i;
125                bool   isInfo[256];
126
127                for (i=0; i<256; i++) isInfo[i] = true;
128                isInfo[UINT('-')] = false;
129                isInfo[UINT('.')] = false;
130                if (compress == COMPRESS_NONINFO_COLUMNS) {
131                    switch (alitype) {
132                        case GB_AT_RNA:
133                        case GB_AT_DNA:
134                            isInfo[UINT('N')] = false;
135                            isInfo[UINT('n')] = false;
136                            break;
137                        case GB_AT_AA:
138                            isInfo[UINT('X')] = false;
139                            isInfo[UINT('x')] = false;
140                            break;
141                        default:
142                            gde_assert(0);
143                            break;
144                    }
145                }
146
147                bool  modified     = false;
148                char *filterString = filter->to_string();
149
150                for (i=0; i<maxalignlen; i++) {
151                    if (filter->use_position(i)) {
152                        bool wantColumn = false;
153
154                        for (size_t n=0; n<numberspecies; n++) {
155                            if (i < seqlen[n]) {
156                                if (isInfo[UINT(the_sequences[n][i])]) {
157                                    wantColumn = true; // have info -> take column
158                                    break;
159                                }
160                            }
161                        }
162                        if (!wantColumn) {
163                            filterString[i] = '0';
164                            modified        = true;
165                        }
166                    }
167                }
168
169                if (modified) {
170                    size_t len = filter->get_length();
171
172                    delete allocatedFilter;
173                    filter = allocatedFilter = new AP_filter(filterString, NULL, len);
174                }
175
176                free(filterString);
177            }
178
179            if (!error) error = filter->is_invalid();
180
181            if (!error) {
182                long   len = filter->get_filtered_length();
183                size_t i;
184
185                for (i=0; i<numberspecies; i++) {
186                    int  c;
187                    long newcount = 0;
188
189                    sequfilt[i]      = (uchar*)malloc((unsigned int)len+1);
190                    sequfilt[i][len] = 0;
191                    memset(sequfilt[i], '.', len); // Generate empty sequences
192
193                    const uchar *simplify = filter->get_simplify_table();
194                    for (size_t col=0; (col<maxalignlen) && (c=the_sequences[i][col]); col++) {
195                        if (filter->use_position(col)) {
196                            sequfilt[i][newcount++] = simplify[c];
197                        }
198                    }
199                }
200            }
201        }
202        free(seqlen);
203
204        if (!error) {
205            GB_transaction ta(db_access.gb_main);
206
207            char *str = filter->to_string();
208            error     = GBT_write_string(db_access.gb_main, AWAR_GDE_EXPORT_FILTER, str);
209            free(str);
210        }
211
212        if (!error) {
213            long number    = 0;
214            int  curelem;
215            int  bad_names = 0;
216
217            int elementtype      = TEXT;
218            int elementtype_init = RNA;
219            switch (typeinfo) {
220                case UNKNOWN_TYPEINFO: gde_assert(0);
221                case BASIC_TYPEINFO: break;
222
223                case DETAILED_TYPEINFO:
224                    switch (alitype) {
225                        case GB_AT_RNA: elementtype = RNA; break;
226                        case GB_AT_DNA: elementtype = DNA; break;
227                        case GB_AT_AA:  elementtype = PROTEIN; break;
228                        default : gde_assert(0); break;
229                    }
230
231                    gde_assert(elementtype != TEXT);
232                    elementtype_init = elementtype;
233                    break;
234            }
235
236            if (!error) {
237                arb_progress progress("Read data from DB", numberspecies);
238                if (the_species) {
239                    for (gb_species = the_species[number]; gb_species && !error; gb_species = the_species[++number]) {
240                        curelem   = Arbdb_get_curelem(dataset);
241                        this_elem = &(dataset.element[curelem]);
242
243                        InitNASeq(this_elem, elementtype_init);
244                        this_elem->gb_species = gb_species;
245
246#define GET_FIELD_CONTENT(fieldname,buffer,bufsize) do {                        \
247                            gbd = GB_entry(gb_species, fieldname);              \
248                            if (gbd) {                                          \
249                                const char *val = GB_read_char_pntr(gbd);       \
250                                strncpy_terminate(buffer, val, bufsize);        \
251                            }                                                   \
252                            else buffer[0] = 0;                                 \
253                        } while(0)
254
255                        GBDATA *gbd;
256                        GET_FIELD_CONTENT("name",      this_elem->short_name, SIZE_SHORT_NAME);
257                        GET_FIELD_CONTENT("author",    this_elem->authority,  SIZE_AUTHORITY);
258                        GET_FIELD_CONTENT("full_name", this_elem->seq_name,   SIZE_SEQ_NAME);
259                        GET_FIELD_CONTENT("acc",       this_elem->id,         SIZE_ID);
260
261                        this_elem->elementtype = elementtype;
262
263                        if (AWTC_name_quality(this_elem->short_name) != 0) bad_names++;
264                        AppendNA_and_free(this_elem, sequfilt[number]);
265                        set_constant_fields(this_elem);
266                        progress.inc_and_check_user_abort(error);
267                    }
268                }
269                else {      // use the_names
270                    unsigned char *species_name;
271
272                    for (species_name=the_names[number]; species_name && !error; species_name=the_names[++number]) {
273                        curelem   = Arbdb_get_curelem(dataset);
274                        this_elem = &(dataset.element[curelem]);
275
276                        InitNASeq(this_elem, elementtype_init);
277                        this_elem->gb_species = 0;
278
279                        strncpy(this_elem->short_name, (char*)species_name, SIZE_SHORT_NAME);
280                        this_elem->authority[0] = 0;
281                        this_elem->seq_name[0]  = 0;
282                        this_elem->id[0]        = 0;
283                        this_elem->elementtype  = elementtype;
284
285                        if (AWTC_name_quality(this_elem->short_name) != 0) bad_names++;
286                        AppendNA_and_free(this_elem, sequfilt[number]);
287                        set_constant_fields(this_elem);
288                        progress.inc_and_check_user_abort(error);
289                    }
290                }
291            }
292
293            if (!error) {
294                if (bad_names) {
295                    aw_message(GBS_global_string("Problematic names found: %i\n"
296                                                 "External program call may fail or produce invalid results.\n"
297                                                 "You might want to use 'Species/Synchronize IDs' and read the associated help.",
298                                                 bad_names));
299                }
300
301                {
302                    unsigned long i;
303                    for (i=0; i<dataset.numelements; i++) {
304                        dataset.maxlen = std::max(dataset.maxlen,
305                                                  dataset.element[i].seqlen+dataset.element[i].offset);
306                    }
307                    for (i=0; i<numberspecies; i++)
308                    {
309                        delete sequfilt[i];
310                    }
311                    free(sequfilt);
312                }
313            }
314        }
315    }
316
317    delete allocatedFilter;
318    if (error) {
319        aw_message(error);
320        return 1; // = aborted
321    }
322    return 0;
323
324}
325
326int ReadArbdb2(NA_Alignment& dataset, AP_filter *filter, GapCompression compress, bool cutoff_stop_codon, TypeInfo typeinfo) {
327    // goes to header: __ATTR__USERESULT
328    GBDATA **the_species;
329    uchar  **the_names;
330    uchar  **the_sequences;
331    long     maxalignlen;
332    long     numberspecies = 0;
333
334    char *error = db_access.get_sequences(the_species, the_names, the_sequences,
335                                          numberspecies, maxalignlen);
336
337    gde_assert(contradicted(the_species, the_names));
338
339    if (error) {
340        aw_message(error);
341        return 1;
342    }
343
344    int res = InsertDatainGDE(dataset, 0, the_names, (unsigned char **)the_sequences, numberspecies, maxalignlen, filter, compress, cutoff_stop_codon, typeinfo);
345    for (long i=0; i<numberspecies; i++) {
346        delete the_sequences[i];
347    }
348    delete the_sequences;
349    if (the_species) delete the_species;
350    else delete the_names;
351
352    return res;
353}
354
355int ReadArbdb(NA_Alignment& dataset, bool marked, AP_filter *filter, GapCompression compress, bool cutoff_stop_codon, TypeInfo typeinfo) {
356    // goes to header: __ATTR__USERESULT
357
358    GBDATA  *gb_species_data = GBT_get_species_data(dataset.gb_main);
359    GBDATA **the_species;
360    long     numberspecies   = 0;
361    long     missingdata     = 0;
362
363    GBDATA *gb_species;
364    if (marked) gb_species = GBT_first_marked_species_rel_species_data(gb_species_data);
365    else gb_species        = GBT_first_species_rel_species_data(gb_species_data);
366
367    while (gb_species) {
368        if (GBT_find_sequence(gb_species, dataset.alignment_name)) numberspecies++;
369        else missingdata++;
370
371        if (marked) gb_species = GBT_next_marked_species(gb_species);
372        else gb_species        = GBT_next_species(gb_species);
373    }
374
375    if (missingdata) {
376        aw_message(GBS_global_string("Skipped %li species which did not contain data in '%s'", missingdata, dataset.alignment_name));
377    }
378
379    the_species   = (GBDATA**)calloc((unsigned int)numberspecies+1, sizeof(GBDATA*));
380    numberspecies = 0;
381
382    if (marked) gb_species = GBT_first_marked_species_rel_species_data(gb_species_data);
383    else gb_species        = GBT_first_species_rel_species_data(gb_species_data);
384
385    while (gb_species) {
386        if (GBT_find_sequence(gb_species, dataset.alignment_name)) {
387            the_species[numberspecies]=gb_species;
388            numberspecies++;
389        }
390
391        if (marked) gb_species = GBT_next_marked_species(gb_species);
392        else gb_species        = GBT_next_species(gb_species);
393    }
394
395    long   maxalignlen   = GBT_get_alignment_len(db_access.gb_main, dataset.alignment_name);
396    char **the_sequences = (char**)calloc((unsigned int)numberspecies+1, sizeof(char*));
397
398    for (long i=0; the_species[i]; i++) {
399        the_sequences[i] = (char *)malloc((size_t)maxalignlen+1);
400        the_sequences[i][maxalignlen] = 0;
401        memset(the_sequences[i], '.', (size_t)maxalignlen);
402        const char *data = GB_read_char_pntr(GBT_find_sequence(the_species[i], dataset.alignment_name));
403        int size = strlen(data);
404        if (size > maxalignlen) size = (int)maxalignlen;
405        strncpy_terminate(the_sequences[i], data, size+1);
406    }
407
408    int res = InsertDatainGDE(dataset, the_species, 0, (unsigned char **)the_sequences, numberspecies, maxalignlen, filter, compress, cutoff_stop_codon, typeinfo);
409    for (long i=0; i<numberspecies; i++) {
410        free(the_sequences[i]);
411    }
412    free(the_sequences);
413    free(the_species);
414
415    return res;
416}
417
418int getelem(NA_Sequence *a, int b) {
419    if (a->seqlen == 0) return -1;
420
421    if (b<a->offset || (b>a->offset+a->seqlen)) {
422        switch (a->elementtype) {
423            case DNA:
424            case RNA:  return 0;
425            case PROTEIN:
426            case TEXT: return '~';
427            case MASK: return '0';
428            default:   return '-';
429        }
430    }
431
432    return a->sequence[b-a->offset];
433}
434
435void putelem(NA_Sequence *a, int b, NA_Base c) {
436    if (b>=(a->offset+a->seqmaxlen)) {
437        Warning("Putelem:insert beyond end of sequence space ignored");
438    }
439    else if (b >= (a->offset)) {
440        a->sequence[b-(a->offset)] = c;
441    }
442    else {
443        NA_Base *temp = (NA_Base*)Calloc(a->seqmaxlen+a->offset-b, sizeof(NA_Base));
444        switch (a->elementtype) {
445            // Pad out with gap characters fron the point of insertion to the offset
446            case MASK:
447                for (int j=b; j<a->offset; j++) temp[j-b] = '0';
448                break;
449
450            case DNA:
451            case RNA:
452                for (int j=b; j<a->offset; j++) temp[j-b] = '\0';
453                break;
454
455            case PROTEIN:
456                for (int j=b; j<a->offset; j++) temp[j-b] = '-';
457                break;
458               
459            case TEXT:
460            default:
461                for (int j=b; j<a->offset; j++) temp[j-b] = ' ';
462                break;
463        }
464
465        for (int j=0; j<a->seqmaxlen; j++) temp[j+a->offset-b] = a->sequence[j];
466        Cfree((char*)a->sequence);
467
468        a->sequence     = temp;
469        a->seqlen      += (a->offset - b);
470        a->seqmaxlen   += (a->offset - b);
471        a->offset       = b;
472        a->sequence[0]  = c;
473    }
474}
475
Note: See TracBrowser for help on using the repository browser.