source: tags/arb_5.1/EDIT4/ED4_dots.cxx

Last change on this file was 5942, checked in by westram, 15 years ago
  • added AW_window::activate (activates window using show() and sending _NET_ACTIVE_WINDOW to WM)
  • use activate in
    • standard popups (all menu/button popups using AW_POPUP)
    • special popup functions that don't bind window to menu/button
    • small requesters (aw_input, aw_question, …)
    • in popup-functions of information windows. But not if info-window is minimized and user just selects a new result in search window.
    • popup message window on each new message
  • no-exit-shells now popdown when X-Button is pressed (e.g. MESSAGE BOX)
  • fixed several special popup functions
  • renamed AW_window::get_show() → is_shown()
File size: 10.3 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : ED4_dots.cxx                                       //
4//   Purpose   : Insert dots where bases may be missing             //
5//                                                                  //
6//   Coded by Ralf Westram (coder@reallysoft.de) in December 2008   //
7//   Institute of Microbiology (Technical University Munich)        //
8//   http://www.arb-home.de/                                        //
9//                                                                  //
10// ================================================================ //
11
12#include "ed4_dots.hxx"
13#include "ed4_class.hxx"
14#include "ed4_visualizeSAI.hxx" // for SAI selection box
15
16#include <arbdbt.h>
17#include <ctype.h>
18
19using namespace std;
20
21#define AWAR_DOT_BASE      "dotmiss/"
22#define AWAR_DOT_SAI       AWAR_DOT_BASE "sai"    // selected SAI
23#define AWAR_DOT_SAI_CHARS AWAR_DOT_BASE "chars"  // handle columns where SAI contains one of these chars
24#define AWAR_DOT_MARKED    AWAR_DOT_BASE "marked" // handle marked only?
25
26struct dot_insert_stat {
27    size_t  pos_count;
28    size_t *position;           // contains 'pos_count' positions, where dots get inserted if sequence contains '-'
29
30    bool marked_only;
31
32    // statistics:
33    size_t dots_inserted;
34    size_t already_there;
35    size_t sequences_checked;
36};
37
38static ED4_returncode dot_sequence_by_consensus(void **cl_insert_stat, void **, ED4_base *base) {
39    GB_ERROR error = 0;
40
41    if (base->is_sequence_info_terminal()) {
42        ED4_sequence_info_terminal *seq_term = base->to_sequence_info_terminal();
43        if (seq_term) {
44            GBDATA *gb_ali = seq_term->data();
45            if (gb_ali) {
46                GBDATA           *gb_species = GB_get_grandfather(gb_ali);
47                bool              marked     = GB_read_flag(gb_species);
48                dot_insert_stat&  stat       = *reinterpret_cast<dot_insert_stat *>(cl_insert_stat);
49
50                if (marked || !stat.marked_only) {
51                    char *sequence = GB_read_string(gb_ali);
52
53                    if (!sequence) {
54                        GB_ERROR err = GB_await_error();
55                        error        = GBS_global_string("No sequence found for '%s'\n(Reason: %s)",
56                                                         GBT_read_name(gb_species), err);
57                    }
58                    else {
59                        size_t length            = GB_read_string_count(gb_ali);
60                        size_t old_dots_inserted = stat.dots_inserted;
61
62                        for (size_t p = 0; p<stat.pos_count; p++) {
63                            size_t pos = stat.position[p];
64
65                            if (pos<length) {
66                                switch (sequence[pos]) {
67                                    case '-':
68                                        sequence[pos] = '.';
69                                        stat.dots_inserted++;
70                                        break;
71
72                                    case '.':
73                                        stat.already_there++;
74                                        break;
75                                   
76                                    default:
77                                        break;
78                                }
79                            }
80                        }
81
82                        if (stat.dots_inserted > old_dots_inserted) { // did sequence change?
83                            error = GB_write_string(gb_ali, sequence);
84                        }
85
86                        free(sequence);
87                        stat.sequences_checked++;
88                    }
89                }
90            }
91        }
92    }
93
94    if (error) {
95        GB_export_error(error);
96        return ED4_R_ERROR;
97    }
98    return ED4_R_OK;
99}
100
101static void dot_missing_bases(AW_window *aww) {
102    ED4_window *ed4w     = ED4_ROOT->get_ed4w();
103    ED4_cursor *cursor   = &ed4w->cursor;
104    ED4_base   *selected = cursor->owner_of_cursor;
105
106    GB_ERROR             error       = 0;
107    ED4_species_manager *species_man = 0;
108   
109    if (selected) {
110        species_man = selected->get_parent(ED4_L_SPECIES)->to_species_manager();
111        if (species_man && !species_man->flag.is_consensus) species_man = 0;
112    }
113
114    if (!species_man) {
115        error = "No consensus selected";
116    }
117    else {
118        AW_root *aw_root = aww->get_root();
119
120        dot_insert_stat stat;
121        stat.dots_inserted     = 0;
122        stat.already_there     = 0;
123        stat.position          = 0;
124        stat.sequences_checked = 0;
125        stat.marked_only       = aw_root->awar(AWAR_DOT_MARKED)->read_int();
126
127        ED4_group_manager *group_manager = selected->get_parent(ED4_L_GROUP)->to_group_manager();
128        {
129            // build list of positions where consensus contains upper case characters:
130            char *consensus = group_manager->table().build_consensus_string();
131            for (int pass = 1; pass <= 2; pass++) {
132                stat.pos_count = 0;
133                for (int pos = 0; consensus[pos]; pos++) {
134                    if (isupper(consensus[pos])) {
135                        if (pass == 2) stat.position[stat.pos_count] = pos;
136                        stat.pos_count++;
137                    }
138                }
139
140                if (pass == 1) stat.position = (size_t*)malloc(stat.pos_count * sizeof(*stat.position));
141            }
142            free(consensus);
143        }
144
145        if (!stat.pos_count) {
146            error = "No consensus column contains upper case characters";
147        }
148        else {
149            // if SAI is selected, reduce list of affected positions
150            char   *sai = 0;
151            size_t  sai_len;
152            {
153                GB_transaction  ta(GLOBAL_gb_main);
154                char           *sai_name = aw_root->awar(AWAR_DOT_SAI)->read_string();
155
156                if (sai_name && sai_name[0]) {
157                    GBDATA *gb_sai     = GBT_expect_SAI(GLOBAL_gb_main, sai_name);
158                    if (!gb_sai) error = GB_await_error();
159                    else {
160                        GBDATA *gb_ali = GBT_read_sequence(gb_sai, ED4_ROOT->alignment_name);
161                        if (!gb_ali) {
162                            error = GBS_global_string("SAI '%s' has no data in '%s'", sai_name, ED4_ROOT->alignment_name);
163                        }
164                        else {
165                            sai     = GB_read_string(gb_ali);
166                            sai_len = GB_read_string_count(gb_ali);
167                        }
168                    }
169                }
170                free(sai_name);
171                error = ta.close(error);
172            }
173
174            if (sai) { // SAI is selected
175                if (!error) {
176                    char *sai_chars = aw_root->awar(AWAR_DOT_SAI_CHARS)->read_string();
177                    if (sai_chars[0] == 0) error = "No SAI characters given -> no column selectable";
178                    else {
179                        size_t k = 0;
180                        size_t p;
181                        for (p = 0; p<stat.pos_count && stat.position[p]<sai_len; p++) {
182                            size_t  pos = stat.position[p];
183                            if (strchr(sai_chars, sai[pos]) != NULL) { // SAI contains one of the 'sai_chars'
184                                stat.position[k++] = pos; // use current position
185                            }
186                        }
187                        stat.pos_count = k;
188
189                        if (!stat.pos_count) error = "SAI selects other columns than consensus. Nothing to do.";
190                    }
191                    free(sai_chars);
192                }
193                free(sai);
194            }
195        }
196
197        if (!error) {
198            e4_assert(stat.pos_count);
199            GB_transaction ta(GLOBAL_gb_main);
200            ED4_returncode result = group_manager->route_down_hierarchy((void**)&stat, NULL, &dot_sequence_by_consensus);
201            if (result == ED4_R_ERROR) error = GB_await_error();
202
203            if (stat.sequences_checked == 0 && !error) {
204                error = GBS_global_string("Group contains no %ssequences", stat.marked_only ? "marked " : "");
205            }
206
207            if (!error) {
208                const char *present = "";
209                if (stat.already_there) {
210                    present = GBS_global_string("Dots already present: %zu  ", stat.already_there);
211                }
212
213                const char *changed = stat.dots_inserted
214                    ? GBS_global_string("Gaps changed into dots: %zu", stat.dots_inserted)
215                    : "No gaps were changed into dots.";
216
217                aw_message(GBS_global_string("%s%s", present, changed));
218            }
219
220            error = ta.close(error);
221        }
222    }
223
224    if (error) aw_message(error);
225}
226
227void ED4_create_dot_missing_bases_awars(AW_root *aw_root, AW_default aw_def) {
228    aw_root->awar_int(AWAR_DOT_MARKED, 0, aw_def);
229    aw_root->awar_string(AWAR_DOT_SAI, "", aw_def);
230    aw_root->awar_string(AWAR_DOT_SAI_CHARS, "", aw_def);
231}
232
233void ED4_popup_dot_missing_bases_window(AW_window *editor_window, AW_CL, AW_CL) {
234    AW_root                 *aw_root = editor_window->get_root();
235    static AW_window_simple *aws     = 0;
236
237    ED4_ROOT->use_window(editor_window);
238
239    if (!aws) {
240        aws = new AW_window_simple;
241
242        aws->init(aw_root, "DOT_MISS_BASES", "Dot potentially missing bases");
243        aws->load_xfig("edit4/missbase.fig");
244
245        aws->at("close");
246        aws->callback(AW_POPDOWN);
247        aws->create_button("CLOSE", "CLOSE", "C");
248       
249        aws->at("help");
250        aws->callback(AW_POPUP_HELP, (AW_CL)"missbase.hlp");
251        aws->create_button("HELP", "HELP","H");
252
253        aws->at("marked");
254        aws->label("Marked species only");
255        aws->create_toggle(AWAR_DOT_MARKED);
256
257        aws->at("SAI");
258        ED4_create_SAI_selection_button(aws, AWAR_DOT_SAI);
259
260        aws->at("SAI_chars");
261        aws->label("contains one of");
262        aws->create_input_field(AWAR_DOT_SAI_CHARS, 20);
263
264        aws->at("cons_def");
265        aws->label("Change definition of");
266        aws->callback(AW_POPUP, (AW_CL)ED4_create_consensus_definition_window, 0);
267        aws->create_button("CONS_DEF", "Consensus", "C");
268
269        aws->at("go");
270        aws->callback(dot_missing_bases);
271        aws->create_button("GO", "GO", "G");
272    }
273
274    e4_assert(aws);
275   
276    aws->activate();
277}
278
Note: See TracBrowser for help on using the repository browser.