source: tags/cvs_2_svn/STAT/ST_quality.cxx

Last change on this file was 5356, checked in by westram, 16 years ago
  • fixed calls to GBS_create_hash
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <math.h>
5#include <ctype.h>
6#include <assert.h>
7
8#include <arbdb.h>
9#include <arbdbt.h>
10#include <aw_awars.hxx>
11#include <BI_helix.hxx>
12
13#include <aw_root.hxx>
14#include <awt_tree.hxx>
15#include <awt_csp.hxx>
16#include "st_ml.hxx"
17#include "st_window.hxx"
18#include "st_quality.hxx"
19
20st_cq_stat::st_cq_stat(int isize) {
21    size = isize;
22    likelihoods = new double[size];
23    square_liks = new double[size];
24    n_elems = new int[size];
25    int i;
26    for (i = 0; i < size; i++) {
27        n_elems[i] = 0;
28        square_liks[i] = 0;
29        likelihoods[i] = 0;
30    }
31}
32
33st_cq_stat::~st_cq_stat() {
34    delete[]square_liks;
35    delete[]likelihoods;
36    delete[]n_elems;
37}
38
39void st_cq_stat::add(int pos, double lik) {
40    assert(pos >= 0 && pos < size);
41    likelihoods[pos] += lik;
42    square_liks[pos] += lik * lik;
43    n_elems[pos]++;
44}
45
46char *st_cq_stat::generate_string() {
47    int i;
48    double sum_lik = 0;
49    double square_sum_lik = 0;
50    int sum_elems = 0;
51    char *res = new char[size + 1];
52    for (i = 0; i < size; i++) {
53        sum_lik += likelihoods[i];
54        square_sum_lik += square_liks[i];
55        sum_elems += n_elems[i];
56        res[i] = '.';
57    }
58    res[size] = 0;
59    if (sum_elems == 0) {
60        return res;
61    }
62    double mean_lik = sum_lik / sum_elems;
63    double mean_sigma = sqrt(square_sum_lik / sum_elems - mean_lik * mean_lik);
64    for (i = 0; i < size; i++) {
65        if (n_elems[i] <= 1)
66            continue;
67
68        double variance = mean_sigma / sqrt(n_elems[i]);
69        double diff = likelihoods[i] / n_elems[i] - mean_lik;
70        double val = .7 * diff / variance;
71        int ival = int (val + .5) + 5;
72        if (ival > 9)
73            ival = 9;
74        if (ival < 0)
75            ival = 0;
76        res[i] = '0' + ival;
77        if (res[i] == '5')
78            res[i] = '-';
79    }
80    return res;
81}
82
83st_cq_info::st_cq_info(int seq_len, int bucket_size) :
84    ss2(2), ss5(5), ssu(seq_len / bucket_size + 1), sscon(2) {
85    ;
86}
87
88st_cq_info::~st_cq_info() {
89    ;
90}
91
92void st_ml_add_sequence_part_to_stat(ST_ML * st_ml, AWT_csp * /*awt_csp */,
93        const char *species_name, int seq_len, int bucket_size,
94        GB_HASH * species_to_info_hash, int start, int end) {
95
96    AP_tree *node = st_ml_convert_species_name_to_node(st_ml, species_name);
97    if (!node)
98        return;
99    ST_sequence_ml *sml = st_ml->get_ml_vectors(0, node, start, end);
100    if (!sml)
101        return; // no statistic available
102    st_cq_info *info;
103    if (start > 0) {
104        info = (st_cq_info *) GBS_read_hash(species_to_info_hash, species_name);
105    } else {
106        info = new st_cq_info(seq_len, bucket_size);
107        GBS_write_hash(species_to_info_hash, species_name, long (info));
108    }
109    int pos;
110    const char *source_sequence = 0;
111    int source_sequence_len = 0;
112
113    if (sml->gb_data) {
114        source_sequence_len = GB_read_string_count(sml->gb_data);
115        source_sequence = GB_read_char_pntr(sml->gb_data);
116    }
117    if (end > source_sequence_len) {
118        end = source_sequence_len;
119    }
120
121    ST_base_vector *vec = sml->tmp_out + start;
122    for (pos = start; pos < end; vec++, pos++) {
123        double max = 0;
124        double v;
125        int    b;
126       
127        for (b = ST_A; b < ST_MAX_BASE; b++) {
128            v = vec->b[b];
129            if (v > max)
130                max = v;
131        }
132        AWT_dna_base base = awt_dna_table.char_to_enum(source_sequence[pos]);
133        if (base != ST_UNKNOWN && base != ST_GAP) { // dont count gaps
134            double val = max / (0.0001 + vec->b[base]);
135            double log_val = log(val);
136            info->ss2.add(pos * 2 / seq_len, log_val);
137            info->ss5.add(pos * 5 / seq_len, log_val);
138            info->ssu.add(pos * info->ssu.size / seq_len, log_val);
139        }
140    }
141}
142
143void st_ml_add_quality_string_to_species(GBDATA * gb_main,
144        const char *alignment_name, const char *species_name, int seq_len,
145        int bucket_size, GB_HASH * species_to_info_hash, st_report_enum report,
146        const char *dest_field) {
147    GBDATA *gb_species = GBT_find_species(gb_main, species_name);
148    if (!gb_species)
149        return; // invalid species
150    st_cq_info *info = (st_cq_info *) GBS_read_hash(species_to_info_hash,
151            species_name);
152    if (!info)
153        return;
154    GBDATA *gb_dest = GB_search(gb_species, dest_field, GB_STRING);
155    GB_ERROR error = 0;
156    if (!gb_dest) {
157        error = GB_get_error();
158    } else {
159        char buffer[256];
160        char *s2 = info->ss2.generate_string();
161        char *s5 = info->ss5.generate_string();
162        char *su = info->ssu.generate_string();
163        snprintf(buffer, 256, "a%s b%s c%s", s2, s5, su);
164        delete[]s2;
165        delete[]s5;
166        error = GB_write_string(gb_dest, buffer);
167
168        if (!error && report) {
169            GBDATA *gb_report = GBT_add_data(gb_species, alignment_name,
170                    "quality", GB_STRING);
171            if (!gb_report) {
172                error = GB_get_error();
173            } else {
174                char *rp = new char[seq_len + 1];
175                rp[seq_len] = 0;
176                int i;
177                for (i = 0; i < seq_len; i++) {
178                    rp[i] = su[i / bucket_size];
179                }
180                error = GB_write_string(gb_report, rp);
181                if (report == ST_QUALITY_REPORT_TEMP) {
182                    GB_set_temporary(gb_report);
183                }
184                delete rp;
185            }
186        }
187        delete[]su;
188    }
189    if (error) {
190        aw_message(error);
191    }
192    delete info;
193    GBS_write_hash(species_to_info_hash, species_name, 0);
194
195}
196
197GB_ERROR st_ml_check_sequence_quality(GBDATA * gb_main, const char *tree_name,
198        const char *alignment_name, AWT_csp * awt_csp, int bucket_size,
199        int marked_only, st_report_enum report, const char *filter_string,
200        const char *dest_field) {
201    AP_filter filter;
202    int seq_len = GBT_get_alignment_len(gb_main, alignment_name);
203    filter.init(filter_string, "0 ", seq_len);
204    ST_ML st_ml(gb_main);
205    GB_ERROR error = st_ml.init(tree_name, alignment_name, 0, marked_only,
206            filter_string, awt_csp);
207    if (error) {
208        return error;
209    }
210
211    GB_HASH *species_to_info_hash = GBS_create_hash(GBT_get_species_count(gb_main), GB_IGNORE_CASE);
212    GB_CSTR *snames = GBT_get_species_names_of_tree((GBT_TREE *) st_ml.tree_root->tree);
213
214    int pos;
215    aw_openstatus("Sequence Quality Check");
216    for (pos = 0; pos < seq_len; pos += ST_MAX_SEQ_PART) {
217        int end = pos + ST_MAX_SEQ_PART - 1;
218        if (end > seq_len)
219            end = seq_len;
220        if (aw_status(pos / double (seq_len))) {
221            return "aborted";
222        }
223        const char **pspecies_name;
224        for (pspecies_name = snames; *pspecies_name; pspecies_name++) {
225            st_ml_add_sequence_part_to_stat(&st_ml, awt_csp, *pspecies_name,
226                    seq_len, bucket_size, species_to_info_hash, pos, end);
227        }
228    }
229    aw_status("Generating Result String");
230    const char **pspecies_name;
231    for (pspecies_name = snames; *pspecies_name; pspecies_name++) {
232        st_ml_add_quality_string_to_species(gb_main, alignment_name,
233                *pspecies_name, seq_len, bucket_size, species_to_info_hash,
234                report, dest_field);
235    }
236    aw_closestatus();
237    free(snames);
238    GBS_free_hash(species_to_info_hash);
239    return NULL;
240}
Note: See TracBrowser for help on using the repository browser.