source: tags/svn.1.5.4/PROBE/PT_io.cxx

Last change on this file was 8041, checked in by westram, 14 years ago

merge from dev [7990] [7991] [7992] [7993] [7994] [7995] [7996] [7998] [8001] [8003] [8005] [8006] [8007] [8008] [8009] [8011] [8012] [8019]

  • added a faked ecoli to ptserver test-db
  • added unit-tests for gene-ptserver
  • rename ptserver testdb
  • ptserver db-cleanup
    • size of mapfile for SSUREF108 is reduced by 85% (3,4Gb → 519Mb)
  • ptserver
    • refactored
      • prefix tree builders
      • probe_input_data
    • removed ptnd_new_match (dead code)
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : PT_io.cxx                                         //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11
12#include "probe.h"
13#include "pt_prototypes.h"
14
15#include <arbdbt.h>
16#include <BI_basepos.hxx>
17#include <arb_progress.h>
18
19int compress_data(char *probestring) {
20    //! change a sequence with normal bases the PT_? format and delete all other signs
21    char    c;
22    char    *src,
23        *dest;
24    dest = src = probestring;
25
26    while ((c=*(src++)))
27    {
28        switch (c) {
29            case 'A':
30            case 'a': *(dest++) = PT_A; break;
31            case 'C':
32            case 'c': *(dest++) = PT_C; break;
33            case 'G':
34            case 'g': *(dest++) = PT_G; break;
35            case 'U':
36            case 'u':
37            case 'T':
38            case 't': *(dest++) = PT_T; break;
39            case 'N':
40            case 'n': *(dest++) = PT_N; break;
41            default: break;
42        }
43
44    }
45    *dest = PT_QU;
46    return 0;
47}
48
49void PT_base_2_string(char *id_string, long len) {
50    //! get a string with readable bases from a string with PT_?
51    char    c;
52    char    *src,
53        *dest;
54    if (!len) len = strlen(id_string);
55    dest = src = id_string;
56
57    while ((len--)>0) {
58        c=*(src++);
59        switch (c) {
60            case PT_A: *(dest++)  = 'A'; break;
61            case PT_C: *(dest++)  = 'C'; break;
62            case PT_G: *(dest++)  = 'G'; break;
63            case PT_T: *(dest++)  = 'U'; break;
64            case PT_N: *(dest++)  = 'N'; break;
65            case 0: *(dest++)     = '0'; break;
66            default: *(dest++)    = c; break;
67        }
68
69    }
70    *dest = '\0';
71}
72
73ARB_ERROR probe_read_data_base(const char *name, bool readOnly) { // goes to header: __ATTR__USERESULT
74    ARB_ERROR error;
75    GB_set_verbose();
76
77    psg.gb_shell = new GB_shell;
78
79    GBDATA *gb_main     = GB_open(name, readOnly ? "r" : "rw");
80    if (!gb_main) error = GB_await_error();
81    else {
82        error = GB_begin_transaction(gb_main);
83        if (!error) {
84            GBDATA *gb_species_data = GB_entry(gb_main, "species_data");
85            if (!gb_species_data) {
86                error = GBS_global_string("Database %s is empty (no species_data)", name);
87            }
88            else {
89                psg.gb_main         = gb_main;
90                psg.gb_species_data = gb_species_data;
91                psg.gb_sai_data     = GBT_get_SAI_data(gb_main);
92            }
93        }
94        error = GB_end_transaction(gb_main, error);
95    }
96    return error;
97}
98
99inline size_t count_uint_32(uint32_t *seq, size_t seqsize, uint32_t cmp) {
100    size_t count = 0;
101    while (count<seqsize && seq[count] == cmp) count++;
102    return count*4;
103}
104
105inline size_t count_char(const char *seq, size_t seqsize, char c, uint32_t c4) {
106    if (seq[0] == c) {
107        size_t count = 1+count_uint_32((uint32_t*)(seq+1), (seqsize-1)/4, c4);
108        for (; count<seqsize && seq[count] == c; ++count) ;
109        return count;
110    }
111    return 0;
112}
113
114inline size_t count_dots(const char *seq, int seqsize) { return count_char(seq, seqsize, '.', 0x2E2E2E2E); }
115inline size_t count_gaps(const char *seq, int seqsize) { return count_char(seq, seqsize, '-', 0x2D2D2D2D); }
116
117inline size_t count_gaps_and_dots(const char *seq, int seqsize) {
118    size_t count = 0;
119    size_t count2;
120    size_t count3;
121
122    do {
123        count2  = count_dots(seq+count, seqsize-count);
124        count  += count2;
125        count3  = count_gaps(seq+count, seqsize-count);
126        count  += count3;
127    }
128    while (count2 || count3);
129    return count;
130}
131
132int probe_compress_sequence(char *seq, int seqsize) {
133    static SmartMallocPtr(uchar) smart_tab;
134    uchar *tab = NULL;
135    if (smart_tab.isNull()) {
136        tab = (uchar *) malloc(256);
137        memset(tab, PT_N, 256);
138        tab['A'] = tab['a'] = PT_A;
139        tab['C'] = tab['c'] = PT_C;
140        tab['G'] = tab['g'] = PT_G;
141        tab['T'] = tab['t'] = PT_T;
142        tab['U'] = tab['u'] = PT_T;
143        tab['.'] = PT_QU;
144        tab[0] = PT_B_UNDEF;
145        smart_tab = tab;
146    }
147
148    tab = &*smart_tab;
149    char *dest = seq;
150    size_t offset = 0;
151
152    while (seq[offset]) {
153        offset += count_gaps(seq + offset, seqsize - offset); // skip over gaps
154
155        uchar c = tab[safeCharIndex(seq[offset++])];
156        if (c == PT_B_UNDEF)
157            break; // already seen terminal zerobyte
158
159        *dest++ = c;
160        if (c == PT_QU) { // TODO: *seq = '.' ???
161            offset += count_gaps_and_dots(seq + offset, seqsize - offset); // skip over gaps and dots
162            // dest[-1] = PT_N; // @@@ uncomment this to handle '.' like 'N' (experimental!!!)
163        }
164    }
165
166    if (dest[-1] != PT_QU) {
167        *dest++ = PT_QU;
168    }
169
170#ifdef ARB_64
171    pt_assert(!((dest - seq) & 0xffffffff00000000)); // must fit into 32 bit
172#endif
173
174    return dest - seq;
175}
176
177static char *probe_read_string_append_point(GBDATA *gb_data, int *psize) {
178    long  len  = GB_read_string_count(gb_data);
179    char *data = GB_read_string(gb_data);
180
181    if (data) {
182        if (data[len - 1] != '.') {
183            char *buffer = (char *) malloc(len + 2);
184            strcpy(buffer, data);
185            buffer[len++] = '.';
186            buffer[len] = 0;
187            freeset(data, buffer);
188        }
189        *psize = len;
190    }
191    else {
192        *psize = 0;
193    }
194    return data;
195}
196
197char *probe_input_data::read_alignment(int *psize) const {
198    char           *buffer     = 0;
199    GBDATA         *gb_species = get_gbdata();
200    GB_transaction  ta(gb_species);
201    GBDATA         *gb_ali     = GB_entry(gb_species, psg.alignment_name);
202
203    if (gb_ali) {
204        GBDATA *gb_data = GB_entry(gb_ali, "data");
205        if (gb_data) buffer = probe_read_string_append_point(gb_data, psize);
206    }
207    return buffer;
208}
209
210char *probe_read_alignment(int j, int *psize) { 
211    return psg.data[j].read_alignment(psize);
212}
213
214GB_ERROR probe_input_data::init(GBDATA *gb_species) {
215    GB_ERROR  error   = NULL;
216    GBDATA   *gb_ali  = GB_entry(gb_species, psg.alignment_name);
217    GBDATA   *gb_data = gb_ali ? GB_entry(gb_ali, "data") : NULL;
218
219    if (!gb_data) {
220        error = GBS_global_string("Species '%s' has no data in '%s'\n", GBT_read_name(gb_species), psg.alignment_name);
221    }
222    else {
223        int   hsize;
224        char *sdata = probe_read_string_append_point(gb_data, &hsize);
225
226        if (!sdata) {
227            error = GBS_global_string("Could not read data in '%s' for species '%s'\n(Reason: %s)\n",
228                                      psg.alignment_name, GBT_read_name(gb_species), GB_await_error());
229        }
230        else {
231            name = strdup(GBT_read_name(gb_species));
232
233            fullname                = GBT_read_string(gb_species, "full_name");
234            if (!fullname) fullname = strdup("");
235
236            gbd   = gb_species;
237
238            set_checksum(GB_checksum(sdata, hsize, 1, ".-"));
239            int csize = probe_compress_sequence(sdata, hsize);
240
241            set_data(GB_memdup(sdata, csize), csize);
242            free(sdata);
243        }
244    }
245
246    return error;
247}
248
249void probe_read_alignments() {
250    // reads sequence data into psg.data
251
252    GB_begin_transaction(psg.gb_main);
253
254    // read ref SAI (e.g. ecoli)
255    {
256        char   *def_ref = GBT_get_default_ref(psg.gb_main);
257        GBDATA *gb_ref  = GBT_find_SAI_rel_SAI_data(psg.gb_sai_data, def_ref);
258
259        psg.ecoli = 0;
260        if (gb_ref) {
261            GBDATA *gb_data = GBT_read_sequence(gb_ref, psg.alignment_name);
262            if (gb_data) {
263                psg.ecoli = GB_read_string(gb_data);
264            }
265        }
266        free(def_ref);
267    }
268
269    int icount = GB_number_of_subentries(psg.gb_species_data);
270   
271    psg.data       = new probe_input_data[icount];
272    psg.data_count = 0;
273
274    int data_missing = 0;
275
276    printf("Database contains %i species\n", icount);
277    {
278        arb_progress progress("Preparing sequence data", icount);
279        int count = 0;
280
281        for (GBDATA *gb_species = GBT_first_species_rel_species_data(psg.gb_species_data);
282             gb_species;
283             gb_species = GBT_next_species(gb_species))
284        {
285            probe_input_data& pid = psg.data[count];
286
287            GB_ERROR error = pid.init(gb_species);
288            if (error) {
289                fputs(error, stderr);
290                fputc('\n', stderr);
291                data_missing++;
292            }
293            else {
294                count++;
295            }
296            progress.inc();
297        }
298
299        pt_assert((count+data_missing) == icount);
300
301        psg.data_count = count;
302        GB_commit_transaction(psg.gb_main);
303    }
304
305   
306
307    if (data_missing) {
308        printf("\n%i species were ignored because of missing data.\n", data_missing);
309    }
310    else {
311        printf("\nAll species contain data in alignment '%s'.\n", psg.alignment_name);
312    }
313    fflush(stdout);
314}
315
316void PT_build_species_hash() {
317    long i;
318    psg.namehash = GBS_create_hash(psg.data_count, GB_MIND_CASE);
319    for (i=0; i<psg.data_count; i++) {
320        GBS_write_hash(psg.namehash, psg.data[i].get_name(), i+1);
321    }
322    unsigned int    max_size;
323    max_size = 0;
324    for (i = 0; i < psg.data_count; i++) {  // get max sequence len
325        max_size = std::max(max_size, (unsigned)(psg.data[i].get_size()));
326        psg.char_count += psg.data[i].get_size();
327    }
328    psg.max_size = max_size;
329
330    if (psg.ecoli) {
331        BI_ecoli_ref *ref = new BI_ecoli_ref;
332        ref->init(psg.ecoli, strlen(psg.ecoli));
333        psg.bi_ecoli = ref;
334    }
335}
336
337
338long PT_abs_2_rel(long pos) {
339    if (!psg.ecoli) return pos;
340    return psg.bi_ecoli->abs_2_rel(pos);
341}
342
Note: See TracBrowser for help on using the repository browser.