source: tags/arb-6.0/PHYLO/PH_main.cxx

Last change on this file was 12303, checked in by westram, 10 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : PH_main.cxx                                       //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "phylo.hxx"
12#include "phwin.hxx"
13#include "PH_display.hxx"
14
15#include <awt_sel_boxes.hxx>
16#include <aw_preset.hxx>
17#include <aw_awar.hxx>
18#include <aw_msg.hxx>
19#include <awt.hxx>
20#include <aw_root.hxx>
21#include <arbdbt.h>
22#include <arb_strarray.h>
23
24#include <iostream>
25#include <macros.hxx>
26#include <aw_question.hxx>
27
28using namespace std;
29
30AW_HEADER_MAIN
31
32GBDATA *GLOBAL_gb_main; // global gb_main for arb_phylo
33char **filter_text;
34
35static void create_filter_text()
36{
37    filter_text = (char **) calloc(FILTER_MODES, sizeof (char *));
38    for (int i=0; i<FILTER_MODES; i++) filter_text[i] = new char[100];
39
40    strcpy(filter_text[DONT_COUNT],           "don't count (ignore)                              ");
41    strcpy(filter_text[SKIP_COLUMN_IF_MAX],   "if occurs most often => forget whole column       ");
42    strcpy(filter_text[SKIP_COLUMN_IF_OCCUR], "if occurs => forget whole column                  ");
43    strcpy(filter_text[COUNT_DONT_USE_MAX],   "count, but do NOT use as maximum                  ");
44    strcpy(filter_text[TREAT_AS_UPPERCASE],   "treat as uppercase character                      ");
45    strcpy(filter_text[TREAT_AS_REGULAR],     "treat as regular character                        ");
46}
47
48static bool valid_alignment_selected(AW_root *aw_root, GBDATA *gb_main) {
49    GB_transaction  ta(gb_main);
50    const char     *aliname = aw_root->awar(AWAR_PHYLO_ALIGNMENT)->read_char_pntr();
51    if (GBT_get_alignment_len(gb_main, aliname)<1) {
52        GB_clear_error();
53        return false;
54    }
55    return true;
56}
57
58static void startup_sequence_cb(AW_window *alisel_window, AW_window *main_window, PH_root *ph_root) {
59    AW_root *aw_root = main_window->get_root();
60    GBDATA  *gb_main = ph_root->get_gb_main();
61    if (valid_alignment_selected(aw_root, gb_main)) {
62        if (alisel_window) alisel_window->hide();
63
64        char   *use = aw_root->awar(AWAR_PHYLO_ALIGNMENT)->read_string();
65        PHDATA *phd = new PHDATA(aw_root, ph_root);
66
67        GB_set_cache_size(gb_main, PH_DB_CACHE_SIZE);
68        phd->load(use);
69        phd->ROOT = phd;
70
71        long len = PHDATA::ROOT->get_seq_len();
72        aw_root->awar(AWAR_PHYLO_FILTER_STOPCOL)->write_int(len);
73        aw_root->awar(AWAR_PHYLO_FILTER_STARTCOL)->set_minmax(0, len);
74        aw_root->awar(AWAR_PHYLO_FILTER_STOPCOL)->set_minmax(0, len);
75
76        main_window->activate();
77        ph_view_species_cb();
78    }
79    else {
80        if (alisel_window) {
81            aw_message("Please select a valid alignment");
82        }
83        else {
84            GBK_terminate("Expected to have a valid alignment");
85        }
86    }
87}
88
89__ATTR__NORETURN static void ph_exit(AW_window *aw_window, PH_root *ph_root) {
90    AW_root *aw_root = aw_window->get_root();
91    shutdown_macro_recording(aw_root);
92
93    GBDATA *gb_main = ph_root->get_gb_main();
94    if (gb_main) {
95        aw_root->unlink_awars_from_DB(gb_main);
96#if defined(DEBUG)
97        AWT_browser_forget_db(gb_main);
98#endif // DEBUG
99        GB_close(gb_main);
100    }
101
102    exit(EXIT_SUCCESS);
103}
104
105
106void expose_cb() {
107    if (PH_display::ph_display->displayed()!=NONE) {
108        PH_display::ph_display->clear_window();
109        PH_display::ph_display->display();
110    }
111}
112
113
114static void resize_cb() {
115    if (PH_display::ph_display) {
116        PH_display::ph_display->resized();
117        PH_display::ph_display->display();
118    }
119}
120
121static GB_ERROR PH_create_ml_multiline_SAI(GB_CSTR sai_name, int nr, GBDATA **gb_sai_ptr, PH_root *ph_root) {
122    GBDATA   *gb_sai = GBT_find_or_create_SAI(ph_root->get_gb_main(), sai_name);
123    GBDATA   *gbd, *gb2;
124    GB_ERROR  error  = ph_check_initialized();
125
126    if (!error) {
127        for (gbd = GB_child(gb_sai); gbd; gbd = gb2) {
128            gb2 = GB_nextChild(gbd);
129
130            const char *key = GB_read_key_pntr(gbd);
131            if (!strcmp(key, "name")) continue;
132            if (!strncmp(key, "ali_", 4)) continue;
133
134            error = GB_delete(gbd);
135            if (error) break;
136        }
137    }
138
139    if (!error) {
140        GBDATA *gb_ali = GB_search(gb_sai, PHDATA::ROOT->use, GB_FIND);
141        if (gb_ali) {
142            for (gbd = GB_child(gb_ali); gbd; gbd = gb2) {
143                gb2 = GB_nextChild(gbd);
144
145                const char *key = GB_read_key_pntr(gbd);
146                if (!strcmp(key, "data")) continue;
147                if (!strcmp(key, "_TYPE")) continue;
148
149                error = GB_delete(gbd);
150                if (error) break;
151            }
152        }
153    }
154
155    GBDATA *gb_data = 0, *gb_TYPE = 0;
156
157    if (!error) {
158        gb_data             = GBT_add_data(gb_sai, PHDATA::ROOT->use, "data", GB_STRING);
159        if (!gb_data) error = GB_await_error();
160    }
161
162    if (!error) {
163        gb_TYPE             = GBT_add_data(gb_sai, PHDATA::ROOT->use, "_TYPE", GB_STRING);
164        if (!gb_TYPE) error = GB_await_error();
165    }
166
167    if (!error && !PHDATA::ROOT->markerline) {
168        error = "Nothing calculated yet";
169    }
170
171    if (!error) {
172        char *full_save_name = 0;
173        FILE *saveResults    = 0;
174        if (nr == 2) {
175            char *save_name = GB_unique_filename("conservationProfile", "gnu");
176            saveResults     = GB_fopen_tempfile(save_name, "w+", &full_save_name);
177            GB_remove_on_exit(full_save_name);
178            free(save_name);
179
180            if (!saveResults) error = GB_await_error();
181        }
182
183        if (!error) {
184            AW_window *main_win   = PH_used_windows::windowList->phylo_main_window;
185            long       minhom     = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MINHOM)->read_int();
186            long       maxhom     = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MAXHOM)->read_int();
187            long       startcol   = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STARTCOL)->read_int();
188            long       stopcol    = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STOPCOL)->read_int();
189            float     *markerline = PHDATA::ROOT->markerline;
190            long       len        = PHDATA::ROOT->get_seq_len();
191
192            char *data = (char *)calloc(sizeof(char), (int)len+1);
193            int   cnt  = 0;
194
195
196            for (int x=0; x<len; x++) {
197                char c;
198
199                if (x<startcol || x>stopcol) {
200                    c = '.';
201                }
202                else {
203                    float ml = markerline[x];
204                    if (nr==2 && ml>0.0) {
205                        ph_assert(saveResults);
206                        fprintf(saveResults, "%i\t%.2f\n", cnt, ml);
207                        cnt++;
208                    }
209
210                    if (ml>=0.0 && ml>=minhom && ml<=maxhom) {
211                        int digit = -1;
212                        switch (nr) {
213                            case 0: // hundred
214                                if (ml>=100.0) digit = 1;
215                                break;
216                            case 1: // ten
217                                if (ml>=10.0) digit = int(ml/10);
218                                break;
219                            case 2: // one
220                                digit = int(ml);
221                                break;
222                            default:
223                                ph_assert(0);
224                                break;
225                        }
226
227                        if (digit<0) c = '-';
228                        else         c = '0' + digit%10;
229                    }
230                    else {
231                        c = '-';
232                    }
233                }
234
235                data[x] = c;
236            }
237            data[len] = 0;
238
239            if (saveResults) {
240                fclose(saveResults);
241                fprintf(stderr, "Note: Frequencies as well saved to '%s'\n", full_save_name);
242            }
243
244            error = GB_write_string(gb_data, data);
245            if (!error) {
246                const char *buffer = GBS_global_string("FMX: Filter by Maximum Frequency: "
247                                                       "Start %li; Stop %li; Minhom %li%%; Maxhom %li%%",
248                                                       startcol, stopcol, minhom, maxhom);
249                error = GB_write_string(gb_TYPE, buffer);
250            }
251            free(data);
252        }
253        free(full_save_name);
254    }
255
256    if (!error) *gb_sai_ptr = gb_sai;
257    return error;
258}
259
260static void PH_save_ml_multiline_cb(AW_window *aww, PH_root *ph_root) {
261    GB_transaction ta(ph_root->get_gb_main());
262
263    GB_ERROR  error     = 0;
264    char     *fname     = aww->get_root()->awar(AWAR_PHYLO_MARKERLINENAME)->read_string();
265    int       fname_len = strlen(fname);
266    {
267        char *digit_appended = (char*)malloc(fname_len+2);
268        memcpy(digit_appended, fname, fname_len);
269        strcpy(digit_appended+fname_len, "0");
270
271        freeset(fname, digit_appended);
272    }
273    GBDATA *gb_sai[3];
274    int i;
275    for (i=0; !error && i<3; i++) {
276        fname[fname_len] = '0'+i;
277        error = PH_create_ml_multiline_SAI(fname, i, &gb_sai[i], ph_root);
278    }
279
280    delete fname;
281
282    aw_message_if(ta.close(error));
283}
284
285static void PH_save_ml_cb(AW_window *aww, PH_root *ph_root) {
286    GBDATA  *gb_main = ph_root->get_gb_main();
287    GB_transaction ta(gb_main);
288
289    char   *fname  = aww->get_root()->awar(AWAR_PHYLO_MARKERLINENAME)->read_string();
290    GBDATA *gb_sai = GBT_find_or_create_SAI(gb_main, fname);
291
292    GB_ERROR error = ph_check_initialized();
293
294    if (!error) {
295        for (GBDATA *gbd = GB_child(gb_sai), *gbnext; gbd; gbd = gbnext) {
296            gbnext = GB_nextChild(gbd);
297
298            const char *key = GB_read_key_pntr(gbd);
299            if (!strcmp(key, "name")) continue;
300            if (!strncmp(key, "ali_", 4)) continue;
301
302            error = GB_delete(gbd);
303            if (error) break;
304        }
305    }
306
307    if (!error) {
308        GBDATA *gb_ali = GB_search(gb_sai, PHDATA::ROOT->use, GB_FIND);
309        if (gb_ali) {
310            for (GBDATA *gbd = GB_child(gb_ali), *gbnext; gbd; gbd = gbnext) {
311                gbnext = GB_nextChild(gbd);
312
313                const char *key = GB_read_key_pntr(gbd);
314                if (!strcmp(key, "bits")) continue;
315                if (!strcmp(key, "_TYPE")) continue;
316
317                error = GB_delete(gbd);
318                if (error) break;
319            }
320        }
321    }
322
323    GBDATA *gb_bits = 0, *gb_TYPE = 0;
324
325    if (!error) {
326        gb_bits             = GBT_add_data(gb_sai, PHDATA::ROOT->use, "bits", GB_BITS);
327        if (!gb_bits) error = GB_await_error();
328    }
329
330    if (!error) {
331        gb_TYPE             = GBT_add_data(gb_sai, PHDATA::ROOT->use, "_TYPE", GB_STRING);
332        if (!gb_TYPE) error = GB_await_error();
333    }
334
335    if (!error && !PHDATA::ROOT->markerline) {
336        error = "Nothing calculated yet";
337    }
338
339    if (!error) {
340        AW_window *main_win   = PH_used_windows::windowList->phylo_main_window;
341        long       minhom     = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MINHOM)->read_int();
342        long       maxhom     = main_win->get_root()->awar(AWAR_PHYLO_FILTER_MAXHOM)->read_int();
343        long       startcol   = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STARTCOL)->read_int();
344        long       stopcol    = main_win->get_root()->awar(AWAR_PHYLO_FILTER_STOPCOL)->read_int();
345        long       len        = PHDATA::ROOT->get_seq_len();
346        char      *bits       = (char *)calloc(sizeof(char), (int)len+1);
347        int        x;
348        float     *markerline = PHDATA::ROOT->markerline;
349
350        for (x=0; x<len; x++) {
351            int bit;
352
353            if (x < startcol || x>stopcol) {
354                bit = 0;
355            }
356            else {
357                float ml = markerline[x];
358
359                if (ml>=0.0 && ml>=minhom && ml<=maxhom) bit = 1;
360                else                     bit = 0;
361
362            }
363            bits[x] = '0'+bit;
364        }
365
366        GB_write_bits(gb_bits, bits, len, "0");
367        char buffer[1024];
368        sprintf(buffer, "FMX: Filter by Maximum Frequency: "
369                "Start %li; Stop %li; Minhom %li%%; Maxhom %li%%",
370                startcol, stopcol, minhom, maxhom);
371
372        GB_write_string(gb_TYPE, buffer);
373
374        free(bits);
375    }
376    free(fname);
377    aw_message_if(ta.close(error));
378}
379
380
381static AW_window *PH_save_markerline(AW_root *root, PH_root *ph_root, int multi_line) {
382    // multi_line ==1 -> save three SAI's usable as column percentage
383
384    root->awar_string(AWAR_PHYLO_MARKERLINENAME, "markerline", AW_ROOT_DEFAULT);
385
386    AW_window_simple *aws = new AW_window_simple;
387
388    if (multi_line) {
389        aws->init(root, "EXPORT_FREQUENCY_LINES", "Export Frequency Lines");
390    }
391    else {
392        aws->init(root, "EXPORT_MARKER_LINE", "Export Marker Line");
393    }
394
395    aws->load_xfig("phylo/save_markerline.fig");
396
397    aws->callback(AW_POPDOWN);
398    aws->at("close");
399    aws->create_button("CLOSE", "CLOSE", "C");
400
401    aws->callback(makeHelpCallback("ph_export_markerline.hlp"));
402    aws->at("help");
403    aws->create_button("HELP", "HELP", "H");
404
405    aws->at("name");
406    aws->create_input_field(AWAR_PHYLO_MARKERLINENAME);
407
408    aws->at("box");
409    awt_create_selection_list_on_sai(ph_root->get_gb_main(), aws, AWAR_PHYLO_MARKERLINENAME, false);
410
411    aws->at("save");
412    if (multi_line) aws->callback(makeWindowCallback(PH_save_ml_multiline_cb, ph_root));
413    else            aws->callback(makeWindowCallback(PH_save_ml_cb, ph_root));
414    aws->create_button("EXPORT", "EXPORT", "E");
415
416    return aws;
417}
418
419static AW_window *create_phyl_main_window(AW_root *aw_root, PH_root *ph_root) {
420    AW_window_menu_modes *awm = new AW_window_menu_modes;
421    awm->init(aw_root, "ARB_PHYLO", "ARB_PHYLO", 830, 630);
422
423    // create menus and menu inserts with callbacks
424
425    AW_gc_manager gcmiddle = AW_manage_GC(awm,
426                                          awm->get_window_id(),
427                                          awm->get_device(AW_MIDDLE_AREA),
428                                          PH_GC_0, PH_GC_0_DRAG, AW_GCM_DATA_AREA,
429                                          makeWindowCallback(resize_cb),
430                                          false, // no color groups
431                                          "#CC9AF8",
432                                          "#SEQUENCE$#000000",
433                                          "#MARKER$#FF0000",
434                                          "NOT_MARKER$#A270C0",
435                                          NULL);
436    AW_manage_GC(awm,
437                 awm->get_window_id(),
438                 awm->get_device(AW_BOTTOM_AREA),
439                 PH_GC_0, PH_GC_0_DRAG, AW_GCM_WINDOW_AREA,
440                 makeWindowCallback(resize_cb),
441                 false, // no color groups
442                 "pink",
443                 "#FOOTER",
444                 NULL);
445
446
447#if defined(DEBUG)
448    AWT_create_debug_menu(awm);
449#endif // DEBUG
450
451    // File menu
452    awm->create_menu("File", "F");
453    awm->insert_menu_topic("export_filter", "Export Filter",      "E", "ph_export_markerline.hlp", AWM_ALL, makeCreateWindowCallback(PH_save_markerline, ph_root, 0));
454    awm->insert_menu_topic("export_freq",   "Export Frequencies", "F", "ph_export_markerline.hlp", AWM_ALL, makeCreateWindowCallback(PH_save_markerline, ph_root, 1));
455    insert_macro_menu_entry(awm, false);
456
457    awm->insert_menu_topic("quit", "Quit", "Q", "quit.hlp", AWM_ALL, makeWindowCallback(ph_exit, ph_root));
458
459    // Calculate menu
460    awm->create_menu("Calculate", "C");
461    awm->insert_menu_topic("calc_column_filter", "Column Filter", "F", "no help", AWM_ALL, makeWindowCallback(ph_view_filter_cb));
462
463    // Config menu
464    awm->create_menu("Config", "o");
465    awm->insert_menu_topic("config_column_filter", "Column Filter", "F", "no help", AWM_ALL, PH_create_filter_window);
466
467    // Properties menu
468    awm->create_menu("Properties", "P");
469    awm->insert_menu_topic("props_menu", "Frame settings ...",   "F", "props_frame.hlp",   AWM_ALL, AW_preset_window);
470    awm->insert_menu_topic("props_data", "Colors and Fonts ...", "C", "ph_props_data.hlp", AWM_ALL, makeCreateWindowCallback(AW_create_gc_window, gcmiddle));
471    awm->sep______________();
472    AW_insert_common_property_menu_entries(awm);
473    awm->sep______________();
474    awm->insert_menu_topic("save_props", "Save Properties (phylo.arb)", "S", "savedef.hlp", AWM_ALL, AW_save_properties);
475
476
477    // set window areas
478    awm->set_info_area_height(30);
479    awm->at(5, 2);
480    awm->auto_space(5, -2);
481
482    awm->callback(makeWindowCallback(ph_exit, ph_root));
483    awm->button_length(0);
484    awm->help_text("quit.hlp");
485    awm->create_button("QUIT", "QUIT");
486
487    awm->callback(makeHelpCallback("phylo.hlp"));
488    awm->button_length(0);
489    awm->create_button("HELP", "HELP", "H");
490
491
492    awm->set_bottom_area_height(120);
493
494    awm->set_expose_callback(AW_MIDDLE_AREA, makeWindowCallback(expose_cb));
495    awm->set_resize_callback(AW_MIDDLE_AREA, makeWindowCallback(resize_cb));
496    awm->set_expose_callback(AW_BOTTOM_AREA, makeWindowCallback(display_status_cb));
497    awm->set_resize_callback(AW_BOTTOM_AREA, makeWindowCallback(display_status_cb));
498
499    return awm;
500}
501
502
503static AW_window *create_select_alignment_window(AW_root *aw_root, AW_window *main_window, PH_root *ph_root) {
504    AW_window_simple *aws = new AW_window_simple;
505
506    aws->init(aw_root, "SELECT_ALIGNMENT", "ARB_PHYLO: Select alignment");
507    aws->load_xfig("phylo/select_ali.fig");
508    aws->button_length(10);
509
510    aws->at("which_alignment");
511    awt_create_selection_list_on_alignments(ph_root->get_gb_main(), (AW_window *)aws, AWAR_PHYLO_ALIGNMENT, "*=");
512
513    aws->auto_space(10, 10);
514
515    aws->at("ok");
516    aws->callback(makeWindowCallback(startup_sequence_cb, main_window, ph_root));
517    aws->create_button("OK", "Ok", "D");
518
519    aws->callback(makeWindowCallback(ph_exit, ph_root));
520    aws->create_button("ABORT", "Abort", "D");
521
522    return aws;
523}
524
525
526
527PH_used_windows::PH_used_windows()
528{
529    memset((char *) this, 0, sizeof(PH_used_windows));
530}
531
532// initialize 'globals'
533PH_used_windows *PH_used_windows::windowList = 0;
534PH_display *PH_display::ph_display=0;
535PHDATA *PHDATA::ROOT = 0;
536
537static void create_variables(AW_root *aw_root, AW_default def) {
538    aw_root->awar_string(AWAR_PHYLO_ALIGNMENT,     "", def);
539    aw_root->awar_string(AWAR_PHYLO_FILTER_FILTER, "", def);
540    PH_create_filter_variables(aw_root, def);
541}
542
543int ARB_main(int argc, char *argv[]) {
544    aw_initstatus();
545
546    GB_shell shell;
547    AW_root  *aw_root = AWT_create_root("phylo.arb", "ARB_PHYLO", need_macro_ability(), &argc, &argv);
548
549    int exitcode = EXIT_SUCCESS;
550    if (argc > 2 || (argc == 2 && strcmp(argv[1], "--help") == 0)) {
551        fprintf(stderr, "Usage: arb_phylo [database]\n");
552        exitcode = EXIT_FAILURE;
553    }
554    else {
555        const char *db_server = (argc == 2 ? argv[1] : ":");
556
557        PH_used_windows *puw = new PH_used_windows;
558        PH_display      *phd = new PH_display;
559
560        PH_root  *ph_root = new PH_root;
561        GB_ERROR  error   = ph_root->open(db_server);
562
563        if (!error) error = configure_macro_recording(aw_root, "ARB_PHYLO", ph_root->get_gb_main());
564        if (!error) {
565            GBDATA *gb_main = ph_root->get_gb_main();
566
567            // create arb_phylo awars :
568            create_variables(aw_root, AW_ROOT_DEFAULT);
569            ARB_init_global_awars(aw_root, AW_ROOT_DEFAULT, gb_main);
570#if defined(DEBUG)
571            AWT_create_db_browser_awars(aw_root, AW_ROOT_DEFAULT);
572#endif // DEBUG
573
574#if defined(DEBUG)
575            AWT_announce_db_to_browser(gb_main, GBS_global_string("ARB-database (%s)", db_server));
576#endif // DEBUG
577
578            create_filter_text();
579
580            // create main window :
581
582            puw->phylo_main_window = create_phyl_main_window(aw_root, ph_root);
583            puw->windowList        = puw;
584
585            phd->ph_display = phd;
586
587            // loading database
588            GB_push_transaction(gb_main);
589
590            ConstStrArray alignment_names;
591            GBT_get_alignment_names(alignment_names, gb_main);
592
593            int num_alignments;
594            for (num_alignments = 0; alignment_names[num_alignments] != 0; num_alignments++) {}
595
596            if (num_alignments > 1) {
597                char *defaultAli = GBT_get_default_alignment(gb_main);
598                aw_root->awar(AWAR_PHYLO_ALIGNMENT)->write_string(defaultAli);
599                create_select_alignment_window(aw_root, puw->phylo_main_window, ph_root)->show();
600                free(defaultAli);
601            }
602            else {
603                aw_root->awar(AWAR_PHYLO_ALIGNMENT)->write_string(alignment_names[0]);
604                startup_sequence_cb(NULL, puw->phylo_main_window, ph_root);
605            }
606            GB_pop_transaction(gb_main);
607
608            AWT_install_cb_guards();
609            aw_root->main_loop();
610        }
611
612        if (error) {
613            aw_popup_exit(error);
614            exitcode = EXIT_FAILURE;
615        }
616    }
617
618    delete aw_root;
619    return exitcode;
620}
621
Note: See TracBrowser for help on using the repository browser.