source: tags/arb-6.0/NTREE/NT_branchAnalysis.cxx

Last change on this file was 11512, checked in by westram, 10 years ago
File size: 7.5 KB
Line 
1// ============================================================== //
2//                                                                //
3//   File      : NT_branchAnalysis.cxx                            //
4//   Purpose   :                                                  //
5//                                                                //
6//   Coded by Ralf Westram (coder@reallysoft.de) in August 2012   //
7//   Institute of Microbiology (Technical University Munich)      //
8//   http://www.arb-home.de/                                      //
9//                                                                //
10// ============================================================== //
11
12#include "NT_local.h"
13#include <TreeCallbacks.hxx>
14#include <aw_awar.hxx>
15#include <awt_canvas.hxx>
16#include <aw_msg.hxx>
17#include <aw_root.hxx>
18
19#define AWAR_BRANCH_ANALYSIS     "branch_analysis"
20#define AWAR_BRANCH_ANALYSIS_TMP "tmp/" AWAR_BRANCH_ANALYSIS
21
22#define AWAR_BA_MIN_REL_DIFF AWAR_BRANCH_ANALYSIS "/min_rel_diff"
23#define AWAR_BA_MIN_ABS_DIFF AWAR_BRANCH_ANALYSIS "/min_abs_diff"
24#define AWAR_BA_MIN_DEPTH    AWAR_BRANCH_ANALYSIS "/min_depth"
25#define AWAR_BA_MIN_ROOTDIST AWAR_BRANCH_ANALYSIS "/min_rootdist"
26#define AWAR_BA_DEGENERATION AWAR_BRANCH_ANALYSIS "/degeneration"
27
28// AISC_MKPT_PROMOTE:class AWT_canvas;
29
30class BranchWindow : virtual Noncopyable {
31    AWT_canvas       *ntw;
32    char             *suffix;
33    AW_awar          *awar_info;
34    AW_window_simple *aws;
35
36    static char *get_suffix(AWT_canvas *ntw) {
37        // suffix depends on canvas
38        return GBS_global_string_copy("_%i", NT_get_canvas_id(ntw));
39    }
40
41    const char *local_awar_name (const char *prefix, const char *name) { return GBS_global_string("%s%s/%s", prefix, suffix, name); }
42
43    void create_awars(AW_root *aw_root);
44    void create_window(AW_root *aw_root);
45
46public:
47    BranchWindow(AW_root *aw_root, AWT_canvas *ntw_)
48        : ntw(ntw_),
49          suffix(get_suffix(ntw))
50    {
51        create_awars(aw_root);
52        create_window(aw_root);
53    }
54
55    ~BranchWindow() {
56        free(suffix);
57    }
58
59    AW_window *get_window() const { return aws; }
60
61private:
62    AW_root *get_awroot() const { return get_window()->get_root(); }
63    AWT_canvas *get_canvas() const { return ntw; }
64    AP_tree *get_tree() const { return AWT_TREE(ntw)->get_root_node(); }
65    GBDATA *get_gbmain() const { return get_canvas()->gb_main; }
66    AW_awar *awar(const char *name) { return get_awroot()->awar(name); }
67
68    void postmark_action() const {
69        get_tree()->compute_tree();
70        get_canvas()->refresh();
71    }
72
73    bool have_tree() {
74        if (get_tree()) return true;
75        set_info("No tree selected");
76        return false;
77    }
78
79public:
80    void set_info(const char *msg) const { awar_info->write_string(msg); }
81    void unmark_all() const { NT_mark_all_cb(NULL, get_canvas(), 0); }
82
83    void markDegeneratedBranches() {
84        if (have_tree()) {
85            GB_transaction ta(get_gbmain());
86            double         degeneration_factor = awar(AWAR_BA_DEGENERATION)->read_float();
87
88            unmark_all();
89            set_info(get_tree()->mark_degenerated_branches(degeneration_factor));
90            postmark_action();
91        }
92    }
93    void markDeepLeafs() {
94        if (have_tree()) {
95            GB_transaction ta(get_gbmain());
96
97            int    min_depth    = awar(AWAR_BA_MIN_DEPTH)->read_int();
98            double min_rootdist = awar(AWAR_BA_MIN_ROOTDIST)->read_float();
99
100            unmark_all();
101            set_info(get_tree()->mark_deep_leafs(min_depth, min_rootdist));
102            postmark_action();
103        }
104    }
105    void markLongBranches() {
106        if (have_tree()) {
107            GB_transaction ta(get_gbmain());
108
109            float min_rel_diff = awar(AWAR_BA_MIN_REL_DIFF)->read_float()/100.0;
110            float min_abs_diff = awar(AWAR_BA_MIN_ABS_DIFF)->read_float();
111
112            unmark_all();
113            set_info(get_tree()->mark_long_branches(min_rel_diff, min_abs_diff));
114            postmark_action();
115        }
116    }
117
118    void analyseDistances() {
119        if (have_tree()) {
120            GB_transaction ta(get_gbmain());
121            set_info(get_tree()->analyse_distances());
122        }
123    }
124};
125
126// --------------------------------------------------------------------------------
127
128static void mark_long_branches_cb       (AW_window *, AW_CL cl_bw) {((BranchWindow*)cl_bw)->markLongBranches(); }
129static void mark_deep_leafs_cb          (AW_window *, AW_CL cl_bw) {((BranchWindow*)cl_bw)->markDeepLeafs(); }
130static void mark_degenerated_branches_cb(AW_window *, AW_CL cl_bw) {((BranchWindow*)cl_bw)->markDegeneratedBranches(); }
131static void unmark_branches_cb          (AW_window *, AW_CL cl_bw) {((BranchWindow*)cl_bw)->unmark_all(); }
132static void distance_analysis_cb        (AW_window *, AW_CL cl_bw) {((BranchWindow*)cl_bw)->analyseDistances(); }
133
134static void tree_changed_cb(AW_root*, AW_CL cl_bw) {
135    BranchWindow *bw = (BranchWindow*)cl_bw;
136    bw->set_info("<tree has changed>");
137}
138
139void BranchWindow::create_awars(AW_root *aw_root) {
140    awar_info = aw_root->awar_string(local_awar_name(AWAR_BRANCH_ANALYSIS_TMP, "info"), "<No analysis performed yet>");
141    aw_root->awar(ntw->user_awar)->add_callback(tree_changed_cb, (AW_CL)this);
142
143    aw_root->awar_float(AWAR_BA_MIN_REL_DIFF, 75);
144    aw_root->awar_float(AWAR_BA_MIN_ABS_DIFF, 0.01);
145
146    aw_root->awar_int(AWAR_BA_MIN_DEPTH, 0);
147    aw_root->awar_float(AWAR_BA_MIN_ROOTDIST, 0.9);
148
149    aw_root->awar_float(AWAR_BA_DEGENERATION, 30);
150}
151
152void BranchWindow::create_window(AW_root *aw_root) {
153    aws = new AW_window_simple;
154
155    aws->init(aw_root, GBS_global_string("BRANCH_ANALYSIS_%s", suffix), "Branch analysis");
156    aws->load_xfig("ad_branch.fig");
157
158    aws->at("close");
159    aws->callback(AW_POPDOWN);
160    aws->create_button("CLOSE", "CLOSE", "C");
161
162    aws->at("help");
163    aws->callback(makeHelpCallback("branch_analysis.hlp"));
164    aws->create_button("HELP", "HELP", "H");
165
166    aws->at("sel");
167    aws->create_button(0, ntw->user_awar, 0, "+");
168
169    aws->at("info");
170    aws->create_text_field(awar_info->awar_name);
171
172    aws->button_length(28);
173   
174    aws->at("dist_analyse");
175    aws->callback(distance_analysis_cb, (AW_CL)this);
176    aws->create_button("ANALYSE", "Analyse distances in tree");
177
178    aws->at("unmark");
179    aws->callback(unmark_branches_cb, (AW_CL)this);
180    aws->create_button("UNMARK", "Unmark all species");
181
182    const int WIDTH = 10;
183
184    aws->at("mark_long");
185    aws->callback(mark_long_branches_cb, (AW_CL)this);
186    aws->create_button("MARK_LONG", "Mark long branches");
187
188    aws->at("min_rel"); aws->create_input_field(AWAR_BA_MIN_REL_DIFF, WIDTH);
189    aws->at("min_abs"); aws->create_input_field(AWAR_BA_MIN_ABS_DIFF, WIDTH);
190
191
192    aws->at("mark_deep");
193    aws->callback(mark_deep_leafs_cb, (AW_CL)this);
194    aws->create_button("MARK_DEEP", "Mark deep leafs");
195
196    aws->at("tree_depth");   aws->create_input_field(AWAR_BA_MIN_DEPTH, WIDTH);
197    aws->at("branch_depth"); aws->create_input_field(AWAR_BA_MIN_ROOTDIST, WIDTH);
198
199    aws->at("mark_degen");
200    aws->callback(mark_degenerated_branches_cb, (AW_CL)this);
201    aws->create_button("MARK_DEGENERATED", "Mark degenerated branches");
202
203    aws->at("degen"); aws->create_input_field(AWAR_BA_DEGENERATION, WIDTH);
204}
205
206AW_window *NT_create_branch_analysis_window(AW_root *aw_root, AWT_canvas *ntw) {
207    static BranchWindow *bw[MAX_NT_WINDOWS] = { MAX_NT_WINDOWS_NULLINIT };
208
209    int ntw_id = NT_get_canvas_id(ntw);
210    if (!bw[ntw_id]) {
211        bw[ntw_id] = new BranchWindow(aw_root, ntw);
212    }
213    nt_assert(bw[ntw_id]);
214    return bw[ntw_id]->get_window();
215}
216
Note: See TracBrowser for help on using the repository browser.