source: branches/profile/PHYLO/PH_data.cxx

Last change on this file was 12043, checked in by westram, 10 years ago
  • reintegrates 'fix' into 'trunk' (fixes #519)
    • this patch wasn't really straightforward, instead each change caused new unexpected side effects. It's quite likely that i didn't detect all of them.
  • adds:
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.2 KB
Line 
1// ============================================================= //
2//                                                               //
3//   File      : PH_data.cxx                                     //
4//   Purpose   :                                                 //
5//                                                               //
6//   Institute of Microbiology (Technical University Munich)     //
7//   http://www.arb-home.de/                                     //
8//                                                               //
9// ============================================================= //
10
11#include "phwin.hxx"
12#include "phylo.hxx"
13#include <arbdbt.h>
14#include <aw_awar.hxx>
15#include <arb_progress.h>
16#include <aw_root.hxx>
17
18char *PHDATA::unload() {
19    PHENTRY *phentry;
20
21    freenull(use);
22    for (phentry=entries; phentry; phentry=phentry->next) {
23        free(phentry->name);
24        free(phentry->full_name);
25        free(phentry);
26    }
27    entries = 0;
28    nentries = 0;
29    return 0;
30}
31
32char *PHDATA::load(char*& Use) {
33    reassign(use, Use);
34    last_key_number = 0;
35
36    GBDATA *gb_main = get_gb_main();
37    GB_push_transaction(gb_main);
38
39    seq_len  = GBT_get_alignment_len(gb_main, use);
40    entries  = NULL;
41    nentries = 0;
42
43    PHENTRY *tail = NULL;
44    for (GBDATA *gb_species = GBT_first_marked_species(gb_main);
45         gb_species;
46         gb_species = GBT_next_marked_species(gb_species))
47    {
48        GBDATA *gb_ali = GB_entry(gb_species, use);
49
50        if (gb_ali) {                                     // existing alignment for this species
51            GBDATA *gb_data = GB_entry(gb_ali, "data");
52
53            if (gb_data) {
54                PHENTRY *new_entry = new PHENTRY;
55
56                new_entry->gb_species_data_ptr = gb_data;
57
58                new_entry->key       = last_key_number++;
59                new_entry->name      = strdup(GBT_read_name(gb_species));
60                new_entry->full_name = GBT_read_string(gb_species, "full_name");
61
62                new_entry->prev = tail;
63                new_entry->next = NULL;
64
65                if (!entries) {
66                    tail = entries = new_entry;
67                }
68                else {
69                    tail->next = new_entry;
70                    tail       = new_entry;
71                }
72                nentries++;
73            }
74        }
75    }
76
77    GB_pop_transaction(gb_main);
78
79    hash_elements = (PHENTRY **)calloc(nentries, sizeof(PHENTRY *));
80
81    {
82        PHENTRY *phentry = entries;
83        for (unsigned int i = 0; i < nentries; i++) {
84            hash_elements[i] = phentry;
85            phentry = phentry->next;
86        }
87    }
88
89    return 0;
90}
91
92
93GB_ERROR PHDATA::save(char *filename) {
94    FILE *out;
95
96    out = fopen(filename, "w");
97    if (!out) {
98        return "Cannot save your File";
99    }
100    unsigned row, col;
101    fprintf(out, "%u\n", nentries);
102    for (row = 0; row<nentries; row++) {
103        fprintf(out, "%-13s", hash_elements[row]->name);
104        for (col=0; col<=row; col++) {
105            fprintf(out, "%7.4f ", matrix->get(row, col)*100.0);
106        }
107        fprintf(out, "\n");
108    }
109    fclose(out);
110    return 0;
111}
112
113void PHDATA::print() {
114    unsigned row, col;
115    printf("    %u\n", nentries);
116    for (row = 0; row<nentries; row++) {
117        printf("%-10s ", hash_elements[row]->name);
118        for (col=0; col<row; col++) {
119            printf("%6f ", matrix->get(row, col));
120        }
121        printf("\n");
122    }
123    printf("\n");
124}
125
126
127GB_ERROR PHDATA::calculate_matrix(const char * /* cancel */, double /* alpha */, PH_TRANSFORMATION /* transformation */) {
128    if (nentries<=1) return "There are not enough species selected";
129
130    matrix = new AP_smatrix(nentries);
131
132    long        i, j, column, reference_table[256];
133    long        options_vector[OPT_COUNT];
134    const char *real_chars, *low_chars, *rest_chars;
135    char        all_chars[100], *sequence_bufferi, *sequence_bufferj;
136    bool        compare[256];
137    AP_FLOAT    number_of_comparisons;
138    bool        bases_used = true;                      // rna oder dna sequence : nur zum testen und Entwicklung
139
140    if (!PHDATA::ROOT) return "nothing loaded yet";
141
142    arb_progress progress("Calculating matrix", matrix_halfsize(nentries, false));
143
144    aw_root = PH_used_windows::windowList->phylo_main_window->get_root();
145    if (bases_used) {
146        real_chars="ACGTU";
147        low_chars="acgtu";
148        rest_chars="MRWSYKVHDBXNmrwsykvhdbxn";
149
150        strcpy(all_chars, real_chars);
151        strcat(all_chars, low_chars);
152        strcat(all_chars, rest_chars);
153    }
154    else {
155        real_chars="ABCDEFGHIKLMNPQRSTVWYZ";
156        low_chars=0;
157        rest_chars="X";
158
159        strcpy(all_chars, real_chars);
160        strcat(all_chars, rest_chars);
161    }
162    strcat(all_chars, ".-");
163
164    // initialize variables
165
166    options_vector[OPT_FILTER_POINT] = aw_root->awar(AWAR_PHYLO_MATRIX_POINT)->read_int();
167    options_vector[OPT_FILTER_MINUS] = aw_root->awar(AWAR_PHYLO_MATRIX_MINUS)->read_int();
168    options_vector[OPT_FILTER_AMBIG] = aw_root->awar(AWAR_PHYLO_MATRIX_REST)->read_int();
169    options_vector[OPT_FILTER_LOWER] = aw_root->awar(AWAR_PHYLO_MATRIX_LOWER)->read_int();
170
171
172    for (i=0; i<256; i++) compare[i]=false;
173    for (i=0; i<long(strlen(real_chars)); i++) compare[(unsigned char)real_chars[i]]=true;
174    for (i=0; i<long(strlen(all_chars)); i++) reference_table[(unsigned char)all_chars[i]]=i;
175
176    // rna or dna sequence: set synonyms
177    if (bases_used) {
178        reference_table[(unsigned char)'U'] = reference_table[(unsigned char)'T']; // T=U
179        reference_table[(unsigned char)'u'] = reference_table[(unsigned char)'t'];
180        reference_table[(unsigned char)'N'] = reference_table[(unsigned char)'X'];
181        reference_table[(unsigned char)'n'] = reference_table[(unsigned char)'x'];
182    }
183
184    distance_table = new AP_smatrix(strlen(all_chars));
185    for (i=0; i<long(strlen(all_chars)); i++) {
186        for (j=0; j<long(strlen(all_chars)); j++) {
187            distance_table->set(i, j, (reference_table[i]==reference_table[j]) ? 0.0 : 1.0);
188        }
189    }
190
191    if (bases_used) // set substitutions T = U ...
192    {
193        distance_table->set(reference_table[(unsigned char)'N'], reference_table[(unsigned char)'X'], 0.0);
194        distance_table->set(reference_table[(unsigned char)'n'], reference_table[(unsigned char)'x'], 0.0);
195        // @@@ why aren't opposite entries used?
196    }
197    distance_table->set(reference_table[(unsigned char)'.'], reference_table[(unsigned char)'-'], 0.0);
198
199    char *filter = aw_root->awar(AWAR_PHYLO_FILTER_FILTER)->read_string();
200
201    // set compare-table according to options_vector
202    switch (options_vector[OPT_FILTER_POINT]) // '.' in column
203    {
204        case 0:  // forget pair
205            // do nothing: compare stays false
206            break;
207        case 1:
208            compare[(unsigned char)'.']=true;
209            break;
210    }
211    switch (options_vector[OPT_FILTER_MINUS]) // '-' in column
212    {
213        case 0:  // forget pair
214            // do nothing: compare stays false
215            break;
216        case 1:
217            compare[(unsigned char)'-']=true;
218            break;
219    }
220    switch (options_vector[OPT_FILTER_AMBIG]) // ambigious character in column
221    {
222        case 0:                 // forget pair
223            // do nothing: compare stays false
224            break;
225        case 1:
226            for (i=0; i<long(strlen(rest_chars)); i++) compare[(unsigned char)rest_chars[i]] = true;
227            break;
228    }
229    if (bases_used) {
230        switch (options_vector[OPT_FILTER_LOWER]) // lower char in column
231        {
232            case 0:             // forget pair
233                // do nothing: compare stays false
234                break;
235            case 1:
236                for (i=0; i<long(strlen(low_chars)); i++) compare[(unsigned char)low_chars[i]] = true;
237                break;
238        }
239    }
240
241
242    // counting routine
243    sequence_bufferi = 0;
244    sequence_bufferj = 0;
245    GB_transaction ta(PHDATA::ROOT->get_gb_main());
246
247    GB_ERROR error = 0;
248    for (i = 0; i < long(nentries); i++) {
249        delete sequence_bufferi;
250        sequence_bufferi = GB_read_string(hash_elements[i]->gb_species_data_ptr);
251        for (j = i + 1; j < long(nentries); j++) {
252            number_of_comparisons = 0.0;
253            delete sequence_bufferj;
254            sequence_bufferj = GB_read_string(hash_elements[j]->gb_species_data_ptr);
255            for (column = 0; column < seq_len; column++) {
256                if (compare[(unsigned char)sequence_bufferi[column]] &&
257                    compare[(unsigned char)sequence_bufferj[column]] &&
258                    filter[column]) {
259                    matrix->set(i, j,
260                                matrix->get(i, j) +
261                                distance_table->get(reference_table[(unsigned char)sequence_bufferi[column]],
262                                                    reference_table[(unsigned char)sequence_bufferj[column]]));
263                    number_of_comparisons++;
264                }
265            }
266            if (number_of_comparisons) {
267                matrix->set(i, j, (matrix->get(i, j) / number_of_comparisons));
268            }
269            progress.inc_and_check_user_abort(error);
270        }
271    }
272    delete sequence_bufferi;
273    delete sequence_bufferj;
274
275    if (error) {
276        delete matrix;
277        matrix = NULL;
278    }
279
280    free(filter);
281   
282    return error;
283}
Note: See TracBrowser for help on using the repository browser.