source: tags/cvs_2_svn/STAT/ST_ml.cxx

Last change on this file was 5390, checked in by westram, 16 years ago
  • TAB-Ex
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.5 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <math.h>
5#include <memory.h>
6// #include <malloc.h>
7#include <ctype.h>
8#include <arbdb.h>
9#include <arbdbt.h>
10#include <aw_awars.hxx>
11#include <awt_tree.hxx>
12#include <awt_csp.hxx>
13#include "st_ml.hxx"
14
15#define st_assert(bed) arb_assert(bed)
16
17AWT_dna_table awt_dna_table;
18
19AWT_dna_table::AWT_dna_table() {
20    int i;
21    for (i = 0; i < 256; i++) {
22        switch (toupper(i)) {
23            case 'A':
24                char_to_enum_table[i] = ST_A;
25                break;
26            case 'C':
27                char_to_enum_table[i] = ST_C;
28                break;
29            case 'G':
30                char_to_enum_table[i] = ST_G;
31                break;
32            case 'T':
33            case 'U':
34                char_to_enum_table[i] = ST_T;
35                break;
36            case '-':
37                char_to_enum_table[i] = ST_GAP;
38                break;
39            default:
40                char_to_enum_table[i] = ST_UNKNOWN;
41        }
42    }
43}
44
45void ST_base_vector::set(char base, ST_base_vector * inv_frequencies) {
46    base = toupper(base);
47    memset((char *) &b[0], 0, sizeof(b));
48    const double k = 1.0 / ST_MAX_BASE;
49    AWT_dna_base ub = awt_dna_table.char_to_enum(base);
50    if (ub != ST_UNKNOWN) {
51        b[ub] = 1.0;
52    } else {
53        b[ST_A] = k;
54        b[ST_C] = k;
55        b[ST_G] = k;
56        b[ST_T] = k;
57        b[ST_GAP] = k;
58    }
59    int i;
60    for (i = 0; i < ST_MAX_BASE; i++) {
61        b[i] *= inv_frequencies->b[i];
62    }
63    ld_lik = 0;
64    lik = 1.0;
65}
66
67void ST_base_vector::print() {
68    int i;
69    for (i = 0; i < ST_MAX_BASE; i++) {
70        printf("%.3G ", b[i]);
71    }
72}
73
74void ST_rate_matrix::set(double dist, double /*TT_ratio */) {
75    int i, j;
76    double k = 1.0 / ST_MAX_BASE;
77    for (i = 0; i < ST_MAX_BASE; i++) {
78        m[i][i] = k + (1.0 - k) * exp(-dist);
79        for (j = 0; j < i; j++) {
80            m[j][i] = m[i][j] = k - k * exp(-dist);
81        }
82    }
83}
84
85void ST_rate_matrix::print() {
86    int i, j;
87    for (i = 0; i < ST_MAX_BASE; i++) {
88        for (j = 0; j < ST_MAX_BASE; j++) {
89            printf("%.3G ", m[i][j]);
90        }
91        printf("\n");
92    }
93}
94
95#if 0
96
97GB_INLINE void ST_rate_matrix::mult(ST_base_vector * in,
98                                    ST_base_vector * out)
99{
100    int     i, j;
101    float  *pm = &m[0][0];
102    double  sum;
103
104    for (i = ST_MAX_BASE - 1; i >= 0; i--) {
105        sum = 0;
106        for (j = ST_MAX_BASE - 1; j >= 0; j--) {
107            sum += *(pm++) * in->b[j];
108        }
109        out->b[i] = sum;
110    }
111    out->ld_lik = in->ld_lik;
112    out->lik = in->lik;
113}
114
115#else
116
117inline void ST_base_vector::mult(ST_base_vector * other) {
118    float  *= &b[0];
119    float  *= &other->b[0];
120    double  a0 = a[0] * c[0];
121    double  a1 = a[1] * c[1];
122    double  a2 = a[2] * c[2];
123    double  a3 = a[3] * c[3];
124    double  a4 = a[4] * c[4];
125
126    b[0]    = a0;
127    b[1]    = a1;
128    b[2]    = a2;
129    b[3]    = a3;
130    b[4]    = a4;
131    ld_lik += other->ld_lik;
132    lik    *= other->lik;
133}
134
135inline void ST_rate_matrix::mult(ST_base_vector * in, ST_base_vector * out) {
136    int    i;
137    float *pm = &m[0][0];
138
139    for (i = ST_MAX_BASE - 1; i >= 0; i--) { // calc revers
140        double sum0 = pm[4] * in->b[0];
141        double sum1 = pm[3] * in->b[1];
142        double sum2 = pm[2] * in->b[2];
143        double sum3 = pm[1] * in->b[3];
144        double sum4 = pm[0] * in->b[4];
145
146        pm        += ST_MAX_BASE;
147        out->b[i]  = (sum0 + sum1) + sum4 + (sum2 + sum3);
148    }
149    out->ld_lik = in->ld_lik;
150    out->lik = in->lik;
151}
152#endif
153
154ST_sequence_ml::ST_sequence_ml(AP_tree_root * rooti, ST_ML * st_mli) :
155    AP_sequence(rooti) {
156    gb_data = 0;
157    st_ml = st_mli;
158    sequence = new ST_base_vector[ST_MAX_SEQ_PART];
159    color_out = NULL;
160    color_out_valid_till = NULL;
161    last_updated = 0;
162}
163
164void st_sequence_callback(GBDATA *, int *cl, gb_call_back_type) {
165    ST_sequence_ml *seq = (ST_sequence_ml *) cl;
166    seq->sequence_change();
167}
168
169void st_sequence_del_callback(GBDATA *, int *cl, gb_call_back_type) {
170    ST_sequence_ml *seq = (ST_sequence_ml *) cl;
171    seq->delete_sequence();
172}
173
174void ST_sequence_ml::delete_sequence() {
175    if (gb_data)
176        GB_remove_callback(gb_data, GB_CB_CHANGED, st_sequence_callback,
177                           (int *) this);
178    if (gb_data)
179        GB_remove_callback(gb_data, GB_CB_DELETE, st_sequence_del_callback,
180                           (int *) this);
181    gb_data = 0;
182}
183
184void ST_sequence_ml::sequence_change() {
185    st_ml->clear_all();
186
187}
188
189ST_sequence_ml::~ST_sequence_ml() {
190    delete[]sequence;
191    delete color_out;
192    delete color_out_valid_till;
193
194    delete_sequence();
195}
196
197AP_sequence *ST_sequence_ml::dup() {
198    return new ST_sequence_ml(root, st_ml);
199}
200
201void ST_sequence_ml::set_gb(GBDATA * gbd) {
202    delete_sequence();
203    gb_data = gbd;
204    GB_add_callback(gb_data, GB_CB_CHANGED, st_sequence_callback, (int *) this);
205    GB_add_callback(gb_data, GB_CB_DELETE, st_sequence_del_callback,
206                    (int *) this);
207}
208
209void ST_sequence_ml::set(const char *) {
210    st_assert(0); // function does nothing, so i assert it wont be called -- ralf may 2008
211}
212
213/** Transform the sequence from character to vector, from st_ml->base to 'to' */
214
215void ST_sequence_ml::set_sequence() {
216    int         i                   = st_ml->base;
217    const char *source_sequence     = 0;
218    int         source_sequence_len = 0;
219
220    if (gb_data) {
221        source_sequence_len = (int) GB_read_string_count(gb_data);
222        source_sequence = GB_read_char_pntr(gb_data);
223    }
224
225    const char *s = source_sequence + st_ml->base;
226    ST_base_vector *dest = sequence;
227    ST_base_vector *freq = st_ml->inv_base_frequencies + st_ml->base;
228    if (st_ml->base < source_sequence_len) {
229        for (; i < st_ml->to; i++) {
230            int c = *(s++);
231            if (!c)
232                break; // end of sequence
233            dest->set(toupper(c), freq);
234            dest++;
235            freq++;
236        }
237    }
238    for (; i < st_ml->to; i++) {
239        dest->set('.', freq);
240        dest++;
241        freq++;
242    }
243}
244
245AP_FLOAT ST_sequence_ml::combine(const AP_sequence *, const AP_sequence *) {
246    return 0.0;
247}
248
249// void ST_sequence_ml::partial_match(const AP_sequence *part, long *overlap, long *penalty) const
250void ST_sequence_ml::partial_match(const AP_sequence *, long *, long *) const {
251    st_assert(0);
252    // should be unused
253}
254
255GB_INLINE void ST_base_vector::check_overflow()
256{
257    double sum = 0.0;
258    int    i;
259
260    for (i = 0; i < ST_MAX_BASE; i++) {
261        sum += b[i];
262    }
263    if (sum < .00001) { // what happend no data, extremely unlikely
264        for (i = 0; i < ST_MAX_BASE; i++)
265            b[i] = .25;
266        ld_lik -= 5; // ???
267    } else {
268        while (sum < 0.25) {
269            sum *= 4;
270            ld_lik -= 2;
271            for (i = 0; i < ST_MAX_BASE; i++) {
272                b[i] *= 4;
273            }
274        }
275    }
276    if (ld_lik> 10000) {
277        printf("overflow\n");
278    }
279}
280
281void ST_sequence_ml::ungo() {
282    last_updated = 0;
283}
284
285void ST_sequence_ml::go(const ST_sequence_ml * lefts, double leftl, const ST_sequence_ml * rights, double rightl) {
286    int             pos;
287    ST_base_vector  hbv;
288    double          lc   = leftl / st_ml->step_size;
289    double          rc   = rightl / st_ml->step_size;
290    int             maxm = st_ml->max_matr - 1;
291    ST_base_vector *lb   = lefts->sequence;
292    ST_base_vector *rb   = rights->sequence;
293    ST_base_vector *dest = sequence;
294
295    for (pos = st_ml->base; pos < st_ml->to; pos++) {
296        if (lb->lik != 1 || rb->lik != 1) {
297            printf("error\n");
298        }
299        int distl = (int) (st_ml->rates[pos] * lc);
300        int distr = (int) (st_ml->rates[pos] * rc);
301        if (distl < 0)
302            distl = -distl;
303        if (distl > maxm)
304            distl = maxm;
305        if (distr < 0)
306            distr = -distr;
307        if (distr > maxm)
308            distr = maxm;
309        st_ml->rate_matrizes[distl].mult(lb, dest);
310        st_ml->rate_matrizes[distr].mult(rb, &hbv);
311        dest->mult(&hbv);
312        dest->check_overflow();
313        if (dest->lik != 1) {
314            printf("error2\n");
315        }
316        dest++;
317        lb++;
318        rb++;
319    }
320}
321
322ST_base_vector *ST_sequence_ml::tmp_out = 0;
323
324/** result will be in tmp_out */
325void ST_sequence_ml::calc_out(ST_sequence_ml * next_branch, double dist) {
326
327    int             pos;
328    ST_base_vector *out   = tmp_out + st_ml->base;
329    double          lc    = dist / st_ml->step_size;
330    ST_base_vector *lefts = next_branch->sequence;
331    int             maxm  = st_ml->max_matr - 1;
332
333    for (pos = st_ml->base; pos < st_ml->to; pos++) {
334        int distl = (int) (st_ml->rates[pos] * lc);
335        if (distl < 0)
336            distl = -distl;
337        if (distl > maxm)
338            distl = maxm;
339        st_ml->rate_matrizes[distl].mult(lefts, out);
340
341        // correct frequencies
342        for (int i = ST_A; i < ST_MAX_BASE; i++) {
343            out->b[i] *= st_ml->base_frequencies[pos].b[i];
344        }
345        lefts++;
346        out++;
347    }
348}
349
350void ST_sequence_ml::print() {
351    int i;
352    for (i = 0; i < ST_MAX_SEQ_PART; i++) {
353        printf("POS %3i  %c     ", i, GB_read_char_pntr(gb_data)[i]);
354        printf("\n");
355    }
356}
357
358ST_ML::ST_ML(GBDATA * gb_maini) {
359    memset((char *) this, 0, sizeof(*this));
360    gb_main = gb_maini;
361}
362
363ST_ML::~ST_ML() {
364    delete tree_root->tree;
365    tree_root->tree = 0;
366    free(alignment_name);
367    delete tree_root;
368    if (hash_2_ap_tree)
369        GBS_free_hash(hash_2_ap_tree);
370    delete not_valid;
371    delete[]base_frequencies;
372    delete[]inv_base_frequencies;
373    delete[]rate_matrizes;
374    if (!awt_csp) {
375        delete rates;
376        delete ttratio;
377    }
378    //delete awt_csp; // no sorry
379}
380
381void ST_ML::print() {
382    ;
383}
384
385/** Translate characters to base frequencies */
386void ST_ML::create_frequencies() {
387    ST_base_vector  *out       = new ST_base_vector[alignment_len];
388    int              i, j;
389    float          **frequency = 0;
390
391    base_frequencies     = out;
392    inv_base_frequencies = new ST_base_vector[alignment_len];
393
394    if (awt_csp)
395        frequency = awt_csp->frequency;
396
397    if (!frequency) {
398        for (i = 0; i < alignment_len; i++) {
399            for (j = ST_A; j < ST_MAX_BASE; j++) {
400                out[i].b[j] = 1.0;
401                inv_base_frequencies[i].b[j] = 1.0;
402            }
403            out[i].lik = 1.0;
404            inv_base_frequencies[i].lik = 1.0;
405        }
406        return;
407    }
408
409    for (i = 0; i < alignment_len; i++) {
410        for (j = ST_A; j < ST_MAX_BASE; j++) {
411            out[i].b[j] = 0.01; // minimal frequency
412        }
413
414        if (frequency['A'])
415            out[i].b[ST_A] += frequency['A'][i];
416        if (frequency['a'])
417            out[i].b[ST_A] += frequency['a'][i];
418
419        if (frequency['C'])
420            out[i].b[ST_C] += frequency['C'][i];
421        if (frequency['c'])
422            out[i].b[ST_C] += frequency['c'][i];
423
424        if (frequency['G'])
425            out[i].b[ST_G] += frequency['G'][i];
426        if (frequency['g'])
427            out[i].b[ST_G] += frequency['g'][i];
428
429        if (frequency['T'])
430            out[i].b[ST_T] += frequency['T'][i];
431        if (frequency['t'])
432            out[i].b[ST_T] += frequency['t'][i];
433        if (frequency['U'])
434            out[i].b[ST_T] += frequency['U'][i];
435        if (frequency['u'])
436            out[i].b[ST_T] += frequency['u'][i];
437
438        if (frequency['-'])
439            out[i].b[ST_GAP] += frequency['-'][i];
440
441        double sum = 0.0;
442
443        for (j = ST_A; j < ST_MAX_BASE; j++)
444            sum += out[i].b[j];
445        for (j = ST_A; j < ST_MAX_BASE; j++)
446            out[i].b[j] += sum * .01; // smoothen frequencies to  avoid crazy values
447        double min = out[i].b[ST_A];
448        for (sum = 0, j = ST_A; j < ST_MAX_BASE; j++) {
449            sum += out[i].b[j];
450            if (out[i].b[j] < min)
451                min = out[i].b[j];
452        }
453        for (j = ST_A; j < ST_MAX_BASE; j++) {
454            if (sum > 0.01) { // valid column ??
455                out[i].b[j] *= ST_MAX_BASE / sum;
456            } else {
457                out[i].b[j] = 1.0; // no
458            }
459            inv_base_frequencies[i].b[j] = min / out[i].b[j];
460        }
461        out[i].lik = 1.0;
462        inv_base_frequencies[i].lik = 1.0;
463
464    }
465}
466
467void ST_ML::insert_tree_into_hash_rek(AP_tree * node) {
468    node->gr.gc = 0;
469    if (node->is_leaf) {
470        GBS_write_hash(hash_2_ap_tree, node->name, (long) node);
471    } else {
472        insert_tree_into_hash_rek(node->leftson);
473        insert_tree_into_hash_rek(node->rightson);
474    }
475}
476
477void ST_ML::create_matrizes(double max_disti, int nmatrizes) {
478    max_dist = max_disti;
479    if (rate_matrizes)
480        delete rate_matrizes;
481    rate_matrizes = new ST_rate_matrix[nmatrizes];
482    max_matr = nmatrizes;
483    step_size = max_dist / max_matr;
484    int i;
485    for (i = 0; i < max_matr; i++) {
486        rate_matrizes[i].set((i + 1) * step_size, 0); // ttratio[i]
487    }
488}
489
490ST_ML *st_delete_species_st_ml = 0;
491
492long ST_ML::delete_species(const char *key, long val) {
493    if (GBS_read_hash(st_delete_species_st_ml->keep_species_hash, key))
494        return val;
495    AP_tree *leaf = (AP_tree *) val;
496    AP_tree *father = leaf->father;
497    leaf->remove();
498    delete father; // deletes me also
499    return 0;
500}
501
502/** this is the real constructor, call only once */
503GB_ERROR ST_ML::init(const char *tree_name, const char *alignment_namei,
504                     const char *species_names, int marked_only,
505                     const char * /*filter_string */, AWT_csp * awt_cspi) {
506
507    GB_transaction dummy(gb_main);
508    GB_ERROR error = 0;
509    if (is_inited) {
510        return GB_export_error("Sorry, once you selected a column statistic you cannot change parameters");
511    }
512    GB_ERROR awt_csp_error = 0;
513    awt_csp = awt_cspi;
514    awt_csp_error = awt_csp->go();
515    if (awt_csp_error) {
516        fprintf(stderr, "%s\n", awt_csp_error);
517    }
518    alignment_name = strdup(alignment_namei);
519    alignment_len = GBT_get_alignment_len(gb_main, alignment_name);
520    if (alignment_len < 10) {
521        delete alignment_name;
522        return (char *) GB_get_error();
523    }
524    AP_tree *tree = new AP_tree(0);
525    tree_root = new AP_tree_root(gb_main, tree, tree_name);
526    error = tree->load(tree_root, 0, GB_FALSE, GB_FALSE, 0, 0); // tree is not linked !!!
527    if (error) {
528        delete tree;
529        delete tree_root;
530        return error;
531    }
532    tree_root->tree = tree;
533
534    // aw_openstatus("Initializing Online Statistic");
535    /* send species into hash table */
536    hash_2_ap_tree = GBS_create_hash(1000, GB_MIND_CASE);
537    // aw_status("Loading Tree");
538    /* delete species */
539    if (species_names) { // keep names
540        error = tree_root->tree->remove_leafs(gb_main, AWT_REMOVE_DELETED);
541        if (error)
542            return error;
543        char *l, *n;
544        keep_species_hash = GBS_create_hash(GBT_get_species_hash_size(gb_main), GB_MIND_CASE);
545        for (l = (char *) species_names; l; l = n) {
546            n = strchr(l, 1);
547            if (n) *n = 0;
548            GBS_write_hash(keep_species_hash, l, 1);
549            if (n) *(n++) = 1;
550        }
551
552        st_delete_species_st_ml = this;
553        insert_tree_into_hash_rek(tree_root->tree);
554        GBS_hash_do_loop(hash_2_ap_tree, (gb_hash_loop_type) delete_species);
555        GBS_free_hash(keep_species_hash);
556        keep_species_hash = 0;
557        GBT_link_tree((GBT_TREE *) tree_root->tree, gb_main, GB_FALSE, 0, 0);
558    } else { // keep marked
559        GBT_link_tree((GBT_TREE *) tree_root->tree, gb_main, GB_FALSE, 0, 0);
560        if (marked_only) {
561            error = tree_root->tree->remove_leafs(gb_main,
562                                                  AWT_REMOVE_NOT_MARKED | AWT_REMOVE_DELETED);
563        } else {
564            error = tree_root->tree->remove_leafs(gb_main, AWT_REMOVE_DELETED);
565        }
566        if (error)
567            return error;
568        if (!tree_root->tree || tree_root->tree->is_leaf) {
569            return GB_export_error(
570                                   "Too few species of the editor are in the tree '%s'",
571                                   tree_name);
572        }
573        insert_tree_into_hash_rek(tree_root->tree);
574    }
575
576    /* calc frequencies */
577
578    if (!awt_csp_error) {
579        rates = awt_csp->rates;
580        ttratio = awt_csp->ttratio;
581    } else {
582        rates = new float[alignment_len];
583        ttratio = new float[alignment_len];
584        for (int i = 0; i < alignment_len; i++) {
585            rates[i] = 1.0;
586            ttratio[i] = 2.0;
587        }
588        awt_csp = 0;
589    }
590    // aw_status("build frequencies");
591    create_frequencies();
592
593    /* set update time */
594
595    latest_modification = GB_read_clock(gb_main);
596
597    /* load sequences */
598    // aw_status("load sequences");
599    tree_root->sequence_template = new ST_sequence_ml(tree_root, this);
600    tree_root->tree->load_sequences_rek(alignment_name, GB_TRUE, GB_TRUE);
601
602    /* create matrizes */
603    create_matrizes(2.0, 1000);
604
605    ST_sequence_ml::tmp_out = new ST_base_vector[alignment_len];
606    is_inited = 1;
607    // aw_closestatus();
608    return 0;
609}
610
611/** go through the tree and calculate the ST_base_vector from bottom to top */
612ST_sequence_ml *ST_ML::do_tree(AP_tree * node) {
613    ST_sequence_ml *seq = static_cast<ST_sequence_ml*>(node->sequence);
614    if (!seq) {
615        seq = new ST_sequence_ml(tree_root, this);
616        node->sequence = (AP_sequence *) seq;
617    }
618
619    if (seq->last_updated)
620        return seq; // already valid !!!
621
622    if (node->is_leaf) {
623        seq->set_sequence();
624    } else {
625        ST_sequence_ml *ls = do_tree(node->leftson);
626        ST_sequence_ml *rs = do_tree(node->rightson);
627        seq->go(ls, node->leftlen, rs, node->rightlen);
628    }
629    seq->last_updated = 1;
630    return seq;
631}
632
633void ST_ML::clear_all() {
634    GB_transaction dummy(gb_main);
635    undo_tree(tree_root->tree);
636    latest_modification = GB_read_clock(gb_main);
637}
638
639void ST_ML::undo_tree(AP_tree * node) {
640    ST_sequence_ml *seq = static_cast<ST_sequence_ml*>(node->sequence);
641    if (!seq) {
642        seq = new ST_sequence_ml(tree_root, this);
643        node->sequence = (AP_sequence *) seq;
644    }
645    seq->ungo();
646    if (!node->is_leaf) {
647        undo_tree(node->leftson);
648        undo_tree(node->rightson);
649    }
650}
651
652/* result will be in tmp_out */
653/* assert end_ali_pos - start_ali_pos < ST_MAX_SEQ_PART */
654// @@@ CAUTION!!! get_ml_vectors has a bug: it does not calculate the last value, if (end_ali_pos-start_ali_pos+1)==ST_MAX_SEQ_PART
655
656ST_sequence_ml *ST_ML::get_ml_vectors(char *species_name, AP_tree * node,
657                                      int start_ali_pos, int end_ali_pos) {
658    if (!node) {
659        if (!hash_2_ap_tree)
660            return 0;
661        node = (AP_tree *) GBS_read_hash(hash_2_ap_tree, species_name);
662        if (!node)
663            return 0;
664    }
665
666    st_assert((end_ali_pos - start_ali_pos + 1) <= ST_MAX_SEQ_PART);
667
668    ST_sequence_ml *seq = (ST_sequence_ml *) node->sequence;
669
670    if (start_ali_pos != base || end_ali_pos > to) {
671        undo_tree(tree_root->tree); // undo everything
672        base = start_ali_pos;
673        to = end_ali_pos;
674    }
675
676    AP_tree *pntr;
677    for (pntr = node->father; pntr; pntr = pntr->father) {
678        ST_sequence_ml *sequ = (ST_sequence_ml *) pntr->sequence;
679        if (sequ)
680            sequ->ungo();
681    }
682
683    node->set_root();
684
685    // get the sequence of my brother
686    AP_tree *brother = node->brother();
687    ST_sequence_ml *seq_of_brother = do_tree(brother);
688
689    seq->calc_out(seq_of_brother, node->father->leftlen
690                  + node->father->rightlen);
691    return seq;
692}
693
694int ST_ML::update_ml_likelihood(char *result[4], int *latest_update,
695                                char *species_name, AP_tree * node)
696// calculates values for 'Detailed column statistics' in ARB_EDIT4
697{
698    if (*latest_update >= latest_modification)
699        return 1;
700
701    // if node isn't given search it using species name:
702    if (!node) {
703        if (!hash_2_ap_tree)
704            return 0;
705        node = (AP_tree *) GBS_read_hash(hash_2_ap_tree, species_name);
706        if (!node)
707            return 0;
708    }
709
710    AWT_dna_base adb[4];
711    int i;
712
713    if (!result[0]) { // allocate Array-elements for result
714        for (i = 0; i < 4; i++) {
715            result[i] = (char *) GB_calloc(1, alignment_len + 1); // 0..alignment_len
716        }
717    }
718
719    for (i = 0; i < 4; i++) {
720        adb[i] = awt_dna_table.char_to_enum("ACGU"[i]);
721    }
722
723    for (int seq_start = 0; seq_start < alignment_len; seq_start
724             += (ST_MAX_SEQ_PART - 1)) {
725        // ^^^^^^^^^^^^^^^^^^^ work-around for bug in get_ml_vectors
726        int seq_end = alignment_len;
727
728        if ((seq_end - seq_start) >= ST_MAX_SEQ_PART) {
729            seq_end = seq_start + (ST_MAX_SEQ_PART - 1);
730        }
731        get_ml_vectors(0, node, seq_start, seq_end);
732    }
733
734    ST_sequence_ml *seq = (ST_sequence_ml *) node->sequence;
735
736    for (int pos = 0; pos < alignment_len; pos++) {
737        ST_base_vector & vec = seq->tmp_out[pos];
738        double sum = vec.b[ST_A] + vec.b[ST_C] + vec.b[ST_G] + vec.b[ST_T]
739            + vec.b[ST_GAP];
740
741        if (sum == 0) {
742            for (i = 0; i < 4; i++) {
743                result[i][pos] = -1;
744            }
745        } else {
746            double div = 100.0 / sum;
747
748            for (i = 0; i < 4; i++) {
749                result[i][pos] = char ((vec.b[adb[i]] * div) + 0.5);
750            }
751        }
752    }
753
754    *latest_update = latest_modification;
755    return 1;
756}
757
758ST_ML_Color *ST_ML::get_color_string(char *species_name, AP_tree * node,
759                                     int start_ali_pos, int end_ali_pos)
760//  (Re-)Calculates the color string of a given node for sequence positions start_ali_pos..end_ali_pos
761{
762
763    // if node isn't given search it using species name:
764    if (!node) {
765        if (!hash_2_ap_tree)
766            return 0;
767        node = (AP_tree *) GBS_read_hash(hash_2_ap_tree, species_name);
768        if (!node)
769            return 0;
770    }
771    // align start_ali_pos/end_ali_pos to previous/next pos divisible by ST_BUCKET_SIZE:
772    start_ali_pos &= ~(ST_BUCKET_SIZE - 1);
773    end_ali_pos = (end_ali_pos & ~(ST_BUCKET_SIZE - 1)) + ST_BUCKET_SIZE - 1;
774    if (end_ali_pos > alignment_len)
775        end_ali_pos = alignment_len;
776
777    double          val;
778    ST_sequence_ml *seq = (ST_sequence_ml *) node->sequence;
779    int             pos;
780
781    if (!seq->color_out) {      // allocate mem for color_out if we not already have it
782        seq->color_out = (ST_ML_Color *) GB_calloc(sizeof(ST_ML_Color),
783                                                   alignment_len);
784        seq->color_out_valid_till = (int *) GB_calloc(sizeof(int),
785                                                      (alignment_len >> LD_BUCKET_SIZE) + ST_BUCKET_SIZE);
786    }
787    // search for first out-dated position:
788    for (pos = start_ali_pos; pos <= end_ali_pos; pos += ST_BUCKET_SIZE) {
789        if (seq->color_out_valid_till[pos >> LD_BUCKET_SIZE]
790            < latest_modification)
791            break;
792    }
793    if (pos > end_ali_pos) { // all positions are up-to-date
794        return seq->color_out; // => return existing result
795    }
796
797    ST_base_vector *vec;
798    int start;
799    for (start = start_ali_pos; start <= end_ali_pos; start += (ST_MAX_SEQ_PART
800                                                                - 1)) {
801        // ^^^^^^^^^^^^^^^^^^^ work-around for bug in get_ml_vectors
802        int end = end_ali_pos;
803        if (end - start >= ST_MAX_SEQ_PART)
804            end = start + (ST_MAX_SEQ_PART - 1);
805        get_ml_vectors(0, node, start, end); // calculates tmp_out (see below)
806    }
807
808    const char *source_sequence = 0;
809    int source_sequence_len = 0;
810
811    if (seq->gb_data) {
812        source_sequence_len = GB_read_string_count(seq->gb_data);
813        source_sequence = GB_read_char_pntr(seq->gb_data);
814    }
815    // create color string in 'outs':
816    ST_ML_Color *outs   = seq->color_out + start_ali_pos;
817    vec                 = seq->tmp_out + start_ali_pos; // tmp_out was calculated by get_ml_vectors above
818    const char  *source = source_sequence + start_ali_pos;
819
820    for (pos = start_ali_pos; pos <= end_ali_pos; pos++) {
821
822        // search max vec for pos:
823        double max = 0;
824        double v;
825        {
826            int b;
827            for (b = ST_A; b < ST_MAX_BASE; b++) {
828                v = vec->b[b];
829                if (v > max)
830                    max = v;
831            }
832        }
833
834        {
835            AWT_dna_base b = awt_dna_table.char_to_enum(*source); // convert seq-character to enum AWT_dna_base
836            *outs = 0;
837            if (b != ST_UNKNOWN) {
838                val = max / (0.0001 + vec->b[b]); // calc ratio of max/real base-char
839                if (val > 1.0) { // if real base-char is NOT the max-likely base-char
840                    *outs = (int) (log(val)); // => insert color
841                }
842            }
843        }
844        outs++;
845        vec++;
846        source++;
847        seq->color_out_valid_till[pos >> LD_BUCKET_SIZE] = latest_modification;
848    }
849    return seq->color_out;
850}
Note: See TracBrowser for help on using the repository browser.