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