source: trunk/SL/GUI_ALIVIEW/ali_filter.cxx

Last change on this file was 19613, checked in by westram, 9 days ago
  • reintegrates 'lib' into 'trunk'
    • replace dynamic library AWT by several static libraries: APP, ARB_SPEC, MASKS, CANVAS, MAPKEY, GUI_TK
    • now also check wrong library dependencies for untested units (only4me)
  • adds: log:branches/lib@19578:19612
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.7 KB
Line 
1// ========================================================= //
2//                                                           //
3//   File      : ali_filter.cxx                              //
4//   Purpose   : GUI to define alignment filters             //
5//                                                           //
6//   Institute of Microbiology (Technical University Munich) //
7//   http://www.arb-home.de/                                 //
8//                                                           //
9// ========================================================= //
10
11#include "ali_filter.hxx"
12#include "sel_boxes.hxx"
13#include "ga_local.h"
14
15#include <aw_awars.hxx>
16#include <aw_root.hxx>
17#include <aw_select.hxx>
18#include <AP_filter.hxx>
19#include <arbdbt.h>
20#include <arb_strbuf.h>
21#include <ad_cb.h>
22#include <arb_str.h>
23
24//! recalc filter
25static void awt_create_select_filter_window_aw_cb(UNFIXED, adfiltercbstruct *cbs) {
26    // update the variables
27    GB_push_transaction(cbs->gb_main);
28
29    AW_root *aw_root        = cbs->awr;
30    char    *target         = aw_root->awar(cbs->def_subname)->read_string();
31    char    *to_free_target = target;
32    char    *use            = aw_root->awar(cbs->def_alignment)->read_string();
33    char    *name           = strchr(target, 1);
34    GBDATA  *gbd            = NULp;
35
36    if (name) {
37        *(name++) = 0;
38        target++;
39        GBDATA *gb_species;
40        if (target[-1] == '@') {
41            gb_species = GBT_find_species(cbs->gb_main, name);
42        }
43        else {
44            gb_species = GBT_find_SAI(cbs->gb_main, name);
45        }
46        if (gb_species) {
47            GBDATA *gb_ali = GB_search(gb_species, use, GB_FIND);
48            if (gb_ali) {
49                gbd = GB_search(gb_ali, target, GB_FIND);
50            }
51            else {
52                GB_clear_error();
53            }
54        }
55    }
56    if (!gbd) {     // nothing selected
57        aw_root->awar(cbs->def_name)->write_string("none");
58        aw_root->awar(cbs->def_source)->write_string("No Filter Sequence ->All Columns Selected");
59        aw_root->awar(cbs->def_filter)->write_string("");
60        aw_root->awar(cbs->def_len)   ->write_int(-1);  // export filter
61    }
62    else {
63        GBDATA *gb_name = GB_get_father(gbd);   // ali_xxxx
64        gb_name = GB_brother(gb_name, "name");
65        char *name2 = GB_read_string(gb_name);
66        aw_root->awar(cbs->def_name)->write_string(name2);
67        free(name2);
68        char *_2filter = aw_root->awar(cbs->def_2filter)->read_string();
69        long _2filter_len = strlen(_2filter);
70
71        char *s, *str;
72        long  len = GBT_get_alignment_len(cbs->gb_main, use);
73        ga_assert(len>0);
74
75        GBS_strstruct buf(5000);
76        long i; for (i=0; i<len; i++) { // build position line
77            if (i%10 == 0) {
78                buf.put('#');
79            }
80            else if (i%5==0) {
81                buf.put('|');
82            }
83            else {
84                buf.put('.');
85            }
86        }
87        buf.put('\n');
88
89        for (int j = 0; j<(len-10)/10; ++j) { // place markers
90            i = j*10;
91
92            char buffer[256];
93            int  printed = sprintf(buffer, "%li", i+1);
94
95            buf.npaste_at(i+1, buffer, printed); // paste string w/o trailing 0-byte!
96        }
97
98        if (GB_read_type(gbd) == GB_STRING) {   // read the filter
99            str = GB_read_string(gbd);
100        }
101        else {
102            str = GB_read_bits(gbd, '-', '+');
103        }
104        buf.cat(str);
105        buf.put('\n');
106        char *canc = aw_root->awar(cbs->def_cancel)->read_string();
107        long min = aw_root->awar(cbs->def_min)->read_int()-1;
108        long max = aw_root->awar(cbs->def_max)->read_int()-1;
109        long flen = 0;
110        for (i=0, s=str; *s; ++s, ++i) {    // transform the filter
111            if (strchr(canc, *s) || (i<min) || (max>0 && i > max)) {
112                *s = '0';
113            }
114            else {
115                if (i > _2filter_len || _2filter[i] != '0') {
116                    *s = '1';
117                    flen++;
118                }
119                else {
120                    *s = '0';
121                }
122            }
123        }
124        buf.cat(str);
125        buf.put('\n');
126
127        aw_root->awar(cbs->def_len)   ->write_int(flen);    // export filter
128        aw_root->awar(cbs->def_filter)->write_string(str);  // export filter
129        aw_root->awar(cbs->def_source)->write_string(buf.get_data()); // set display
130
131        free(_2filter);
132        free(str);
133        free(canc);
134    }
135    free(to_free_target);
136    free(use);
137    GB_pop_transaction(cbs->gb_main);
138}
139
140static void awt_add_sequences_to_list(adfiltercbstruct *cbs, const char *use, GBDATA *gb_extended, const char *pre, char tpre) {
141    GBDATA *gb_ali = GB_entry(gb_extended, use);
142
143    if (gb_ali) {
144        int         count   = 0;
145        GBDATA     *gb_type = GB_entry(gb_ali, "_TYPE");
146        const char *TYPE    = gb_type ? GB_read_char_pntr(gb_type) : "";
147        char       *name    = ARB_strdup(GBT_get_name_or_description(gb_extended));
148        GBDATA     *gb_data;
149
150        for (gb_data = GB_child(gb_ali); gb_data; gb_data = GB_nextChild(gb_data)) {
151            if (GB_read_key_pntr(gb_data)[0] != '_') {
152                long type = GB_read_type(gb_data);
153
154                if (type == GB_BITS || type == GB_STRING) {
155                    char *str;
156
157                    if (count) str = GBS_global_string_copy("%s%-20s SEQ_%i %s", pre, name, count + 1, TYPE);
158                    else str       = GBS_global_string_copy("%s%-20s       %s", pre, name, TYPE);
159
160                    const char *target = GBS_global_string("%c%s%c%s", tpre, GB_read_key_pntr(gb_data), 1, name);
161
162                    cbs->filterlist->insert(str, target);
163                    free(str);
164                    count++;
165                }
166            }
167        }
168        free(name);
169    }
170}
171
172static void awt_create_select_filter_window_gb_cb(UNFIXED, adfiltercbstruct *cbs) {
173    // update list widget and variables
174    GB_push_transaction(cbs->gb_main);
175
176    if (cbs->filterlist) {
177        char *use = cbs->awr->awar(cbs->def_alignment)->read_string();
178
179        cbs->filterlist->clear();
180        cbs->filterlist->insert_default("none", "");
181
182        const char *name = GBT_readOrCreate_char_pntr(cbs->gb_main, AWAR_SPECIES_NAME, "");
183        if (name[0]) {
184            GBDATA *gb_species = GBT_find_species(cbs->gb_main, name);
185            if (gb_species) {
186                awt_add_sequences_to_list(cbs, use, gb_species, "SEL. SPECIES:", '@');
187            }
188        }
189
190        for (GBDATA *gb_extended = GBT_first_SAI(cbs->gb_main);
191             gb_extended;
192             gb_extended = GBT_next_SAI(gb_extended))
193        {
194            awt_add_sequences_to_list(cbs, use, gb_extended, "", ' ');
195        }
196
197        cbs->filterlist->update();
198        free(use);
199    }
200    awt_create_select_filter_window_aw_cb(NULp, cbs);
201    GB_pop_transaction(cbs->gb_main);
202}
203
204void awt_create_filter_awars(AW_root *aw_root, AW_default aw_def, const char *awar_filtername, const char *awar_mapto_alignment) {
205    /*! creates awars needed for filter definition (see awt_create_select_filter())
206     *
207     * created awars: "SOMETHING/name" (as specified in param awar_filtername; type STRING)
208     *                "SOMETHING/filter" (type STRING)
209     *                "SOMETHING/alignment" (type STRING)
210     *
211     * The names of the created awars are available via adfiltercbstruct (after awt_create_select_filter() was called).
212     *
213     * @param aw_root              application root
214     * @param aw_def               database for created awars
215     * @param awar_filtername      name of filtername awar (has to be "SOMETHING/name";
216     *                             awarname should start with "tmp/", saving in properties/db does not work correctly!).
217     * @param awar_mapto_alignment if given, "SOMETHING/alignment" is mapped to this awar
218     */
219
220    ga_assert(ARB_strBeginsWith(awar_filtername, "tmp/")); // see above
221
222    char *awar_filter    = GBS_string_eval(awar_filtername, "/name=/filter");
223    char *awar_alignment = GBS_string_eval(awar_filtername, "/name=/alignment");
224
225    aw_root->awar_string(awar_filtername, "none", aw_def);
226    aw_root->awar_string(awar_filter,     "",     aw_def);
227
228    AW_awar *awar_ali = aw_root->awar_string(awar_alignment, "", aw_def);
229    if (awar_mapto_alignment) awar_ali->map(awar_mapto_alignment);
230
231    free(awar_alignment);
232    free(awar_filter);
233}
234
235adfiltercbstruct *awt_create_select_filter(AW_root *aw_root, GBDATA *gb_main, const char *def_name) {
236    /*! Create filter definition (allowing customization and programmatical use of a filter)
237     *
238     * @param aw_root  application root
239     * @param gb_main  DB root node
240     * @param def_name filtername awarname (name has to be "SOMETHING/name"; create using awt_create_filter_awars())
241     * @return the filter definition
242     * @see awt_create_select_filter_win(), awt_get_filter()
243     */
244
245    adfiltercbstruct *acbs   = new adfiltercbstruct;
246    acbs->gb_main            = gb_main;
247    AW_default        aw_def = AW_ROOT_DEFAULT;
248
249    GB_push_transaction(acbs->gb_main);
250
251#if defined(DEBUG)
252    {
253        int len = strlen(def_name);
254
255        ga_assert(len >= 5);
256        ga_assert(strcmp(def_name+len-5, "/name") == 0); // filter awar has to be "SOMETHING/name"
257    }
258#endif                          // DEBUG
259
260    acbs->def_name      = GBS_string_eval(def_name, "/name=/name");
261    acbs->def_filter    = GBS_string_eval(def_name, "/name=/filter");
262    acbs->def_alignment = GBS_string_eval(def_name, "/name=/alignment");
263
264    acbs->def_min = GBS_string_eval(def_name, "*/name=tmp/*1/min:tmp/tmp=tmp");
265    acbs->def_max = GBS_string_eval(def_name, "*/name=tmp/*1/max:tmp/tmp=tmp");
266    aw_root->awar_int(acbs->def_min)->add_callback(makeRootCallback(awt_create_select_filter_window_aw_cb, acbs));
267    aw_root->awar_int(acbs->def_max)->add_callback(makeRootCallback(awt_create_select_filter_window_aw_cb, acbs));
268
269    acbs->def_len = GBS_string_eval(def_name, "*/name=tmp/*1/len:tmp/tmp=tmp");
270    aw_root->awar_int(acbs->def_len);
271
272    acbs->def_dest = GBS_string_eval(def_name, "*/name=tmp/*1/dest:tmp/tmp=tmp");
273    aw_root->awar_string(acbs->def_dest, "", aw_def);
274
275    acbs->def_cancel = GBS_string_eval(def_name, "*/name=*1/cancel");
276    aw_root->awar_string(acbs->def_cancel, ".0-=", aw_def);
277
278    acbs->def_simplify = GBS_string_eval(def_name, "*/name=*1/simplify");
279    aw_root->awar_int(acbs->def_simplify, 0, aw_def);
280
281    acbs->def_subname = GBS_string_eval(def_name, "*/name=tmp/*1/subname:tmp/tmp=tmp");
282    aw_root->awar_string(acbs->def_subname);
283
284    acbs->def_source = GBS_string_eval(def_name, "*/name=tmp/*/source:tmp/tmp=tmp");
285    aw_root->awar_string(acbs->def_source);
286
287    acbs->def_2name      = GBS_string_eval(def_name, "*/name=tmp/*/2filter/name:tmp/tmp=tmp");
288    acbs->def_2filter    = GBS_string_eval(def_name, "*/name=tmp/*/2filter/filter:tmp/tmp=tmp");
289    acbs->def_2alignment = GBS_string_eval(def_name, "*/name=tmp/*/2filter/alignment:tmp/tmp=tmp");
290
291    aw_root->awar_string(acbs->def_2name)->write_string("- none -");
292    aw_root->awar_string(acbs->def_2filter);
293    aw_root->awar_string(acbs->def_2alignment);
294
295    acbs->filterlist = NULp;
296    acbs->aw_filt    = NULp;
297    acbs->awr        = aw_root;
298    {
299        char *fname = aw_root->awar(acbs->def_name)->read_string();
300        const char *fsname = GBS_global_string(" data%c%s", 1, fname);
301        free(fname);
302        aw_root->awar(acbs->def_subname)->write_string(fsname);     // cause an callback
303    }
304
305    aw_root->awar(acbs->def_subname)->touch();      // cause an callback
306
307    GBDATA *gb_sai_data = GBT_get_SAI_data(acbs->gb_main);
308    GBDATA *gb_sel      = GB_search(acbs->gb_main, AWAR_SPECIES_NAME, GB_STRING);
309
310    GB_add_callback(gb_sai_data, GB_CB_CHANGED, makeDatabaseCallback(awt_create_select_filter_window_gb_cb, acbs));
311    GB_add_callback(gb_sel,      GB_CB_CHANGED, makeDatabaseCallback(awt_create_select_filter_window_gb_cb, acbs));
312
313    aw_root->awar(acbs->def_alignment)->add_callback(makeRootCallback(awt_create_select_filter_window_gb_cb, acbs));
314    aw_root->awar(acbs->def_2filter)  ->add_callback(makeRootCallback(awt_create_select_filter_window_aw_cb, acbs));
315    aw_root->awar(acbs->def_subname)  ->add_callback(makeRootCallback(awt_create_select_filter_window_aw_cb, acbs));
316
317    awt_create_select_filter_window_gb_cb(NULp, acbs);
318
319    GB_pop_transaction(acbs->gb_main);
320    return acbs;
321}
322
323
324void awt_set_awar_to_valid_filter_good_for_tree_methods(GBDATA *gb_main, AW_root *awr, const char *awar_name) {
325    GB_transaction transaction_var(gb_main);
326    if (GBT_find_SAI(gb_main, "POS_VAR_BY_PARSIMONY")) {
327        awr->awar(awar_name)->write_string("POS_VAR_BY_PARSIMONY");
328        return;
329    }
330    if (GBT_find_SAI(gb_main, "ECOLI")) {
331        awr->awar(awar_name)->write_string("ECOLI");
332        return;
333    }
334}
335
336static AW_window *awt_create_2_filter_window(AW_root *aw_root, adfiltercbstruct *acbs) {
337    GB_push_transaction(acbs->gb_main);
338    aw_root->awar(acbs->def_2alignment)->map(acbs->def_alignment);
339    adfiltercbstruct *s2filter = awt_create_select_filter(aw_root, acbs->gb_main, acbs->def_2name);
340    GB_pop_transaction(acbs->gb_main);
341    return awt_create_select_filter_win(aw_root, s2filter);
342}
343
344char *AWT_get_combined_filter_name(AW_root *aw_root, GB_CSTR prefix) {
345    char       *combined_name = aw_root->awar(GBS_global_string("%s/filter/name", prefix))->read_string(); // "gde/filter/name"
346    const char *awar_prefix   = AWAR_GDE_FILTER;
347    const char *awar_repeated = "/2filter";
348    const char *awar_postfix  = "/name";
349    int         prefix_len    = strlen(awar_prefix);
350    int         repeated_len  = strlen(awar_repeated);
351    int         postfix_len   = strlen(awar_postfix);
352    int         count;
353
354    for (count = 1; ; ++count) {
355        char *awar_name = new char[prefix_len + count*repeated_len + postfix_len + 1];
356        strcpy(awar_name, awar_prefix);
357        int c;
358        for (c=0; c<count; ++c) strcat(awar_name, awar_repeated);
359        strcat(awar_name, awar_postfix);
360
361        AW_awar *awar_found = aw_root->awar_no_error(awar_name);
362        delete [] awar_name;
363
364        if (!awar_found) break; // no more filters defined
365        char *content = awar_found->read_string();
366
367        if (!strstr(content, "none")) { // don't add filters named 'none'
368            freeset(combined_name, GBS_global_string_copy("%s/%s", combined_name, content));
369        }
370    }
371
372    return combined_name;
373}
374
375AW_window *awt_create_select_filter_win(AW_root *aw_root, adfiltercbstruct *acbs) {
376    //! Create a filter selection window
377    if (!acbs->aw_filt) {
378        GB_push_transaction(acbs->gb_main);
379
380        AW_window_simple *aws = new AW_window_simple;
381        {
382            int   checksum  = GBS_checksum(acbs->def_name, true, NULp);
383            char *window_id = GBS_global_string_copy("FILTER_SELECT_%i", checksum); // make window id awar specific
384
385            aws->init(aw_root, window_id, "Select Filter");
386            free(window_id);
387        }
388        aws->load_xfig("awt/filter.fig");
389        aws->button_length(10);
390
391        aws->at("close");
392        aws->callback(AW_POPDOWN);
393        aws->create_button("CLOSE", "CLOSE", "C");
394
395        aws->at("help"); aws->callback(makeHelpCallback("sel_fil.hlp"));
396        aws->create_button("HELP", "HELP", "H");
397
398        acbs->aw_filt = aws; // store the filter selection window in 'acbs'
399
400        aws->at("filter");
401        acbs->filterlist = aws->create_selection_list(acbs->def_subname, 20, 3);
402
403        aws->at("2filter");
404        aws->callback(makeCreateWindowCallback(awt_create_2_filter_window, acbs));
405        aws->create_button(acbs->def_2name, acbs->def_2name);
406
407        aws->at("zero");
408        aws->callback(makeWindowCallback(awt_create_select_filter_window_aw_cb, acbs)); // @@@ used as INPUTFIELD_CB (see #559)
409        aws->create_input_field(acbs->def_cancel, 10);
410
411        aws->at("sequence");
412        aws->create_text_field(acbs->def_source, 1, 1);
413
414        aws->at("min");
415        aws->create_input_field(acbs->def_min, 4);
416
417        aws->at("max");
418        aws->create_input_field(acbs->def_max, 4);
419
420        aws->at("simplify");
421        aws->create_option_menu(acbs->def_simplify);
422        aws->insert_option("ORIGINAL DATA", "O", 0);
423        aws->sens_mask(AWM_EXP);
424        aws->insert_option("TRANSVERSIONS ONLY", "T", 1);
425        aws->insert_option("SIMPLIFIED AA", "A", 2);
426        aws->sens_mask(AWM_ALL);
427        aws->update_option_menu();
428
429        awt_create_select_filter_window_gb_cb(NULp, acbs);
430
431        aws->button_length(7);
432        aws->at("len");
433        aws->create_button(NULp, acbs->def_len);
434
435        GB_pop_transaction(acbs->gb_main);
436    }
437
438    return acbs->aw_filt;
439}
440
441AP_filter *awt_get_filter(adfiltercbstruct *acbs) {
442    /*! create a filter from settings made in filter-definition window.
443     *  always returns a filter, use awt_invalid_filter() to check for validity
444     */
445    AP_filter *filter = NULp;
446
447    if (acbs) {
448        GB_push_transaction(acbs->gb_main);
449
450        char *filter_string = acbs->awr->awar(acbs->def_filter)->read_string();
451        long  len           = 0;
452
453        {
454            char *use = acbs->awr->awar(acbs->def_alignment)->read_string();
455
456            len = GBT_get_alignment_len(acbs->gb_main, use);
457            free(use);
458        }
459
460        if (len <= 0) { // no valid alignment -> uses dummy filter
461            GB_clear_error();
462        }
463        else { // have alignment
464            filter  = new AP_filter(filter_string, "0", len);
465            int sim = acbs->awr->awar(acbs->def_simplify)->read_int();
466            filter->enable_simplify((AWT_FILTER_SIMPLIFY)sim);
467            free(filter_string);
468        }
469
470        GB_pop_transaction(acbs->gb_main);
471    }
472
473    if (!filter) filter = new AP_filter(0); // empty dummy filter
474    return filter;
475}
476
477GB_ERROR awt_invalid_filter(AP_filter *filter) {
478    return filter->is_invalid();
479}
480
481void awt_destroy_filter(AP_filter *filter) {
482    delete filter;
483}
Note: See TracBrowser for help on using the repository browser.