source: tags/arb_5.5/STAT/ST_ml.cxx

Last change on this file was 6010, checked in by westram, 15 years ago
  • ST_ML
    • in case of error (while loading tree), set tree variables to NULL
    • dont try to free NULL-tree in dtor
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 24.6 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    if (tree_root) {
365        delete tree_root->tree;
366        tree_root->tree = 0;
367        delete tree_root;
368    }
369    free(alignment_name);
370    if (hash_2_ap_tree) GBS_free_hash(hash_2_ap_tree);
371    delete not_valid;
372    delete[]base_frequencies;
373    delete[]inv_base_frequencies;
374    delete[]rate_matrizes;
375    if (!awt_csp) {
376        delete rates;
377        delete ttratio;
378    }
379    //delete awt_csp; // no sorry
380}
381
382void ST_ML::print() {
383    ;
384}
385
386/** Translate characters to base frequencies */
387void ST_ML::create_frequencies() {
388    ST_base_vector  *out       = new ST_base_vector[alignment_len];
389    int              i, j;
390    float          **frequency = 0;
391
392    base_frequencies     = out;
393    inv_base_frequencies = new ST_base_vector[alignment_len];
394
395    if (awt_csp)
396        frequency = awt_csp->frequency;
397
398    if (!frequency) {
399        for (i = 0; i < alignment_len; i++) {
400            for (j = ST_A; j < ST_MAX_BASE; j++) {
401                out[i].b[j] = 1.0;
402                inv_base_frequencies[i].b[j] = 1.0;
403            }
404            out[i].lik = 1.0;
405            inv_base_frequencies[i].lik = 1.0;
406        }
407        return;
408    }
409
410    for (i = 0; i < alignment_len; i++) {
411        for (j = ST_A; j < ST_MAX_BASE; j++) {
412            out[i].b[j] = 0.01; // minimal frequency
413        }
414
415        if (frequency['A'])
416            out[i].b[ST_A] += frequency['A'][i];
417        if (frequency['a'])
418            out[i].b[ST_A] += frequency['a'][i];
419
420        if (frequency['C'])
421            out[i].b[ST_C] += frequency['C'][i];
422        if (frequency['c'])
423            out[i].b[ST_C] += frequency['c'][i];
424
425        if (frequency['G'])
426            out[i].b[ST_G] += frequency['G'][i];
427        if (frequency['g'])
428            out[i].b[ST_G] += frequency['g'][i];
429
430        if (frequency['T'])
431            out[i].b[ST_T] += frequency['T'][i];
432        if (frequency['t'])
433            out[i].b[ST_T] += frequency['t'][i];
434        if (frequency['U'])
435            out[i].b[ST_T] += frequency['U'][i];
436        if (frequency['u'])
437            out[i].b[ST_T] += frequency['u'][i];
438
439        if (frequency['-'])
440            out[i].b[ST_GAP] += frequency['-'][i];
441
442        double sum = 0.0;
443
444        for (j = ST_A; j < ST_MAX_BASE; j++)
445            sum += out[i].b[j];
446        for (j = ST_A; j < ST_MAX_BASE; j++)
447            out[i].b[j] += sum * .01; // smoothen frequencies to  avoid crazy values
448        double min = out[i].b[ST_A];
449        for (sum = 0, j = ST_A; j < ST_MAX_BASE; j++) {
450            sum += out[i].b[j];
451            if (out[i].b[j] < min)
452                min = out[i].b[j];
453        }
454        for (j = ST_A; j < ST_MAX_BASE; j++) {
455            if (sum > 0.01) { // valid column ??
456                out[i].b[j] *= ST_MAX_BASE / sum;
457            } else {
458                out[i].b[j] = 1.0; // no
459            }
460            inv_base_frequencies[i].b[j] = min / out[i].b[j];
461        }
462        out[i].lik = 1.0;
463        inv_base_frequencies[i].lik = 1.0;
464
465    }
466}
467
468void ST_ML::insert_tree_into_hash_rek(AP_tree * node) {
469    node->gr.gc = 0;
470    if (node->is_leaf) {
471        GBS_write_hash(hash_2_ap_tree, node->name, (long) node);
472    } else {
473        insert_tree_into_hash_rek(node->leftson);
474        insert_tree_into_hash_rek(node->rightson);
475    }
476}
477
478void ST_ML::create_matrizes(double max_disti, int nmatrizes) {
479    max_dist = max_disti;
480    if (rate_matrizes)
481        delete rate_matrizes;
482    rate_matrizes = new ST_rate_matrix[nmatrizes];
483    max_matr = nmatrizes;
484    step_size = max_dist / max_matr;
485    int i;
486    for (i = 0; i < max_matr; i++) {
487        rate_matrizes[i].set((i + 1) * step_size, 0); // ttratio[i]
488    }
489}
490
491long ST_ML::delete_species(const char *key, long val, void *cd_st_ml) {
492    ST_ML *st_ml = (ST_ML*)cd_st_ml;
493
494    if (GBS_read_hash(st_ml->keep_species_hash, key)) {
495        return val;
496    }
497    else {
498        AP_tree *leaf   = (AP_tree *) val;
499        AP_tree *father = leaf->father;
500        leaf->remove();
501        delete father;                              // deletes me also
502       
503        return 0;
504    }
505}
506
507inline GB_ERROR tree_size_ok(AP_tree_root *tree_root) {
508    GB_ERROR error = NULL;
509
510    if (!tree_root->tree || tree_root->tree->is_leaf) {
511        const char *tree_name = tree_root->tree_name;
512       
513        error = GBS_global_string("Too few species remained in tree '%s'", tree_name);
514    }
515    return error;
516}
517
518/** this is the real constructor, call only once */
519GB_ERROR ST_ML::init(const char *tree_name, const char *alignment_namei,
520                     const char *species_names, int marked_only,
521                     const char * /*filter_string */, AWT_csp * awt_cspi) {
522
523    GB_transaction ta(gb_main);
524    GB_ERROR error = 0;
525    if (is_inited) {
526        return GB_export_error("Sorry, once you selected a column statistic you cannot change parameters");
527    }
528    GB_ERROR awt_csp_error = 0;
529    awt_csp = awt_cspi;
530    awt_csp_error = awt_csp->go();
531    if (awt_csp_error) {
532        fprintf(stderr, "%s\n", awt_csp_error);
533    }
534    alignment_name = strdup(alignment_namei);
535    alignment_len = GBT_get_alignment_len(gb_main, alignment_name);
536    if (alignment_len < 10) {
537        free(alignment_name);
538        return GB_await_error();
539    }
540    AP_tree *tree = new AP_tree(0);
541    tree_root = new AP_tree_root(gb_main, tree, tree_name);
542    error = tree->load(tree_root, 0, GB_FALSE, GB_FALSE, 0, 0); // tree is not linked !!!
543    if (error) {
544        delete tree;            tree      = 0;
545        delete tree_root;       tree_root = 0;
546        return error;
547    }
548    tree_root->tree = tree;
549
550    // aw_openstatus("Initializing Online Statistic");
551    /* send species into hash table */
552    hash_2_ap_tree = GBS_create_hash(1000, GB_MIND_CASE);
553    // aw_status("Loading Tree");
554    /* delete species */
555    if (species_names) { // keep names
556        tree_root->tree->remove_leafs(gb_main, AWT_REMOVE_DELETED);
557
558        error = tree_size_ok(tree_root);
559        if (error) return ta.close(error);
560
561        char *l, *n;
562        keep_species_hash = GBS_create_hash(GBT_get_species_hash_size(gb_main), GB_MIND_CASE);
563        for (l = (char *) species_names; l; l = n) {
564            n = strchr(l, 1);
565            if (n) *n = 0;
566            GBS_write_hash(keep_species_hash, l, 1);
567            if (n) *(n++) = 1;
568        }
569
570        insert_tree_into_hash_rek(tree_root->tree);
571        GBS_hash_do_loop(hash_2_ap_tree, delete_species, this);
572        GBS_free_hash(keep_species_hash);
573        keep_species_hash = 0;
574        GBT_link_tree((GBT_TREE *) tree_root->tree, gb_main, GB_FALSE, 0, 0);
575    }
576    else { // keep marked
577        GBT_link_tree((GBT_TREE *) tree_root->tree, gb_main, GB_FALSE, 0, 0);
578        tree_root->tree->remove_leafs(gb_main, (marked_only ? AWT_REMOVE_NOT_MARKED : 0)|AWT_REMOVE_DELETED);
579       
580        error = tree_size_ok(tree_root);
581        if (error) return ta.close(error);
582
583        insert_tree_into_hash_rek(tree_root->tree);
584    }
585
586    /* calc frequencies */
587
588    if (!awt_csp_error) {
589        rates = awt_csp->rates;
590        ttratio = awt_csp->ttratio;
591    }
592    else {
593        rates = new float[alignment_len];
594        ttratio = new float[alignment_len];
595        for (int i = 0; i < alignment_len; i++) {
596            rates[i] = 1.0;
597            ttratio[i] = 2.0;
598        }
599        awt_csp = 0;
600    }
601    // aw_status("build frequencies");
602    create_frequencies();
603
604    /* set update time */
605
606    latest_modification = GB_read_clock(gb_main);
607
608    /* load sequences */
609    // aw_status("load sequences");
610    tree_root->sequence_template = new ST_sequence_ml(tree_root, this);
611    tree_root->tree->load_sequences_rek(alignment_name, GB_TRUE, GB_TRUE);
612
613    /* create matrizes */
614    create_matrizes(2.0, 1000);
615
616    ST_sequence_ml::tmp_out = new ST_base_vector[alignment_len];
617    is_inited = 1;
618    // aw_closestatus();
619    return 0;
620}
621
622/** go through the tree and calculate the ST_base_vector from bottom to top */
623ST_sequence_ml *ST_ML::do_tree(AP_tree * node) {
624    ST_sequence_ml *seq = static_cast<ST_sequence_ml*>(node->sequence);
625    if (!seq) {
626        seq = new ST_sequence_ml(tree_root, this);
627        node->sequence = (AP_sequence *) seq;
628    }
629
630    if (seq->last_updated)
631        return seq; // already valid !!!
632
633    if (node->is_leaf) {
634        seq->set_sequence();
635    } else {
636        ST_sequence_ml *ls = do_tree(node->leftson);
637        ST_sequence_ml *rs = do_tree(node->rightson);
638        seq->go(ls, node->leftlen, rs, node->rightlen);
639    }
640    seq->last_updated = 1;
641    return seq;
642}
643
644void ST_ML::clear_all() {
645    GB_transaction dummy(gb_main);
646    undo_tree(tree_root->tree);
647    latest_modification = GB_read_clock(gb_main);
648}
649
650void ST_ML::undo_tree(AP_tree * node) {
651    ST_sequence_ml *seq = static_cast<ST_sequence_ml*>(node->sequence);
652    if (!seq) {
653        seq = new ST_sequence_ml(tree_root, this);
654        node->sequence = (AP_sequence *) seq;
655    }
656    seq->ungo();
657    if (!node->is_leaf) {
658        undo_tree(node->leftson);
659        undo_tree(node->rightson);
660    }
661}
662
663/* result will be in tmp_out */
664/* assert end_ali_pos - start_ali_pos < ST_MAX_SEQ_PART */
665// @@@ 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
666
667ST_sequence_ml *ST_ML::get_ml_vectors(char *species_name, AP_tree * node,
668                                      int start_ali_pos, int end_ali_pos) {
669    if (!node) {
670        if (!hash_2_ap_tree)
671            return 0;
672        node = (AP_tree *) GBS_read_hash(hash_2_ap_tree, species_name);
673        if (!node)
674            return 0;
675    }
676
677    st_assert((end_ali_pos - start_ali_pos + 1) <= ST_MAX_SEQ_PART);
678
679    ST_sequence_ml *seq = (ST_sequence_ml *) node->sequence;
680
681    if (start_ali_pos != base || end_ali_pos > to) {
682        undo_tree(tree_root->tree); // undo everything
683        base = start_ali_pos;
684        to = end_ali_pos;
685    }
686
687    AP_tree *pntr;
688    for (pntr = node->father; pntr; pntr = pntr->father) {
689        ST_sequence_ml *sequ = (ST_sequence_ml *) pntr->sequence;
690        if (sequ)
691            sequ->ungo();
692    }
693
694    node->set_root();
695
696    // get the sequence of my brother
697    AP_tree *brother = node->brother();
698    ST_sequence_ml *seq_of_brother = do_tree(brother);
699
700    seq->calc_out(seq_of_brother, node->father->leftlen
701                  + node->father->rightlen);
702    return seq;
703}
704
705int ST_ML::update_ml_likelihood(char *result[4], int *latest_update,
706                                char *species_name, AP_tree * node)
707// calculates values for 'Detailed column statistics' in ARB_EDIT4
708{
709    if (*latest_update >= latest_modification)
710        return 1;
711
712    // if node isn't given search it using species name:
713    if (!node) {
714        if (!hash_2_ap_tree)
715            return 0;
716        node = (AP_tree *) GBS_read_hash(hash_2_ap_tree, species_name);
717        if (!node)
718            return 0;
719    }
720
721    AWT_dna_base adb[4];
722    int i;
723
724    if (!result[0]) { // allocate Array-elements for result
725        for (i = 0; i < 4; i++) {
726            result[i] = (char *) GB_calloc(1, alignment_len + 1); // 0..alignment_len
727        }
728    }
729
730    for (i = 0; i < 4; i++) {
731        adb[i] = awt_dna_table.char_to_enum("ACGU"[i]);
732    }
733
734    for (int seq_start = 0; seq_start < alignment_len; seq_start
735             += (ST_MAX_SEQ_PART - 1)) {
736        // ^^^^^^^^^^^^^^^^^^^ work-around for bug in get_ml_vectors
737        int seq_end = alignment_len;
738
739        if ((seq_end - seq_start) >= ST_MAX_SEQ_PART) {
740            seq_end = seq_start + (ST_MAX_SEQ_PART - 1);
741        }
742        get_ml_vectors(0, node, seq_start, seq_end);
743    }
744
745    ST_sequence_ml *seq = (ST_sequence_ml *) node->sequence;
746
747    for (int pos = 0; pos < alignment_len; pos++) {
748        ST_base_vector & vec = seq->tmp_out[pos];
749        double sum = vec.b[ST_A] + vec.b[ST_C] + vec.b[ST_G] + vec.b[ST_T]
750            + vec.b[ST_GAP];
751
752        if (sum == 0) {
753            for (i = 0; i < 4; i++) {
754                result[i][pos] = -1;
755            }
756        } else {
757            double div = 100.0 / sum;
758
759            for (i = 0; i < 4; i++) {
760                result[i][pos] = char ((vec.b[adb[i]] * div) + 0.5);
761            }
762        }
763    }
764
765    *latest_update = latest_modification;
766    return 1;
767}
768
769ST_ML_Color *ST_ML::get_color_string(char *species_name, AP_tree * node,
770                                     int start_ali_pos, int end_ali_pos)
771//  (Re-)Calculates the color string of a given node for sequence positions start_ali_pos..end_ali_pos
772{
773
774    // if node isn't given search it using species name:
775    if (!node) {
776        if (!hash_2_ap_tree)
777            return 0;
778        node = (AP_tree *) GBS_read_hash(hash_2_ap_tree, species_name);
779        if (!node)
780            return 0;
781    }
782    // align start_ali_pos/end_ali_pos to previous/next pos divisible by ST_BUCKET_SIZE:
783    start_ali_pos &= ~(ST_BUCKET_SIZE - 1);
784    end_ali_pos = (end_ali_pos & ~(ST_BUCKET_SIZE - 1)) + ST_BUCKET_SIZE - 1;
785    if (end_ali_pos > alignment_len)
786        end_ali_pos = alignment_len;
787
788    double          val;
789    ST_sequence_ml *seq = (ST_sequence_ml *) node->sequence;
790    int             pos;
791
792    if (!seq->color_out) {      // allocate mem for color_out if we not already have it
793        seq->color_out = (ST_ML_Color *) GB_calloc(sizeof(ST_ML_Color),
794                                                   alignment_len);
795        seq->color_out_valid_till = (int *) GB_calloc(sizeof(int),
796                                                      (alignment_len >> LD_BUCKET_SIZE) + ST_BUCKET_SIZE);
797    }
798    // search for first out-dated position:
799    for (pos = start_ali_pos; pos <= end_ali_pos; pos += ST_BUCKET_SIZE) {
800        if (seq->color_out_valid_till[pos >> LD_BUCKET_SIZE]
801            < latest_modification)
802            break;
803    }
804    if (pos > end_ali_pos) { // all positions are up-to-date
805        return seq->color_out; // => return existing result
806    }
807
808    ST_base_vector *vec;
809    int start;
810    for (start = start_ali_pos; start <= end_ali_pos; start += (ST_MAX_SEQ_PART
811                                                                - 1)) {
812        // ^^^^^^^^^^^^^^^^^^^ work-around for bug in get_ml_vectors
813        int end = end_ali_pos;
814        if (end - start >= ST_MAX_SEQ_PART)
815            end = start + (ST_MAX_SEQ_PART - 1);
816        get_ml_vectors(0, node, start, end); // calculates tmp_out (see below)
817    }
818
819    const char *source_sequence = 0;
820    int source_sequence_len = 0;
821
822    if (seq->gb_data) {
823        source_sequence_len = GB_read_string_count(seq->gb_data);
824        source_sequence = GB_read_char_pntr(seq->gb_data);
825    }
826    // create color string in 'outs':
827    ST_ML_Color *outs   = seq->color_out + start_ali_pos;
828    vec                 = seq->tmp_out + start_ali_pos; // tmp_out was calculated by get_ml_vectors above
829    const char  *source = source_sequence + start_ali_pos;
830
831    for (pos = start_ali_pos; pos <= end_ali_pos; pos++) {
832
833        // search max vec for pos:
834        double max = 0;
835        double v;
836        {
837            int b;
838            for (b = ST_A; b < ST_MAX_BASE; b++) {
839                v = vec->b[b];
840                if (v > max)
841                    max = v;
842            }
843        }
844
845        {
846            AWT_dna_base b = awt_dna_table.char_to_enum(*source); // convert seq-character to enum AWT_dna_base
847            *outs = 0;
848            if (b != ST_UNKNOWN) {
849                val = max / (0.0001 + vec->b[b]); // calc ratio of max/real base-char
850                if (val > 1.0) { // if real base-char is NOT the max-likely base-char
851                    *outs = (int) (log(val)); // => insert color
852                }
853            }
854        }
855        outs++;
856        vec++;
857        source++;
858        seq->color_out_valid_till[pos >> LD_BUCKET_SIZE] = latest_modification;
859    }
860    return seq->color_out;
861}
Note: See TracBrowser for help on using the repository browser.