source: branches/stable/SEQ_QUALITY/SQ_main.cxx

Last change on this file was 17262, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
Line 
1//  ==================================================================== //
2//                                                                       //
3//    File      : SQ_main.cxx                                            //
4//    Purpose   : Entrypoint to Seq. Quality analysis; calls functions   //
5//                                                                       //
6//                                                                       //
7//  Coded by Juergen Huber in July 2003 - February 2004                  //
8//  Coded by Kai Bader (baderk@in.tum.de) in 2007 - 2008                 //
9//  Copyright Department of Microbiology (Technical University Munich)   //
10//                                                                       //
11//  Visit our web site at: http://www.arb-home.de/                       //
12//                                                                       //
13//  ==================================================================== //
14
15#include "seq_quality.h"
16#include "SQ_functions.h"
17
18#include <awt_filter.hxx>
19#include <awt_sel_boxes.hxx>
20
21#include <aw_awars.hxx>
22#include <aw_msg.hxx>
23#include <aw_root.hxx>
24
25#include <arb_progress.h>
26#include <TreeNode.h>
27#include <arb_global_defs.h>
28#include <awt_config_manager.hxx>
29
30// --------------------------------------------------------------------------------
31
32#define AWAR_SQ_PERM "seq_quality/"     // saved in properties
33#define AWAR_SQ_TEMP "tmp/seq_quality/" // not saved in properties
34
35#define AWAR_SQ_WEIGHT_BASES     AWAR_SQ_PERM "weight_bases"
36#define AWAR_SQ_WEIGHT_DEVIATION AWAR_SQ_PERM "weight_deviation"
37#define AWAR_SQ_WEIGHT_HELIX     AWAR_SQ_PERM "weight_helix"
38#define AWAR_SQ_WEIGHT_CONSENSUS AWAR_SQ_PERM "weight_consensus"
39#define AWAR_SQ_WEIGHT_IUPAC     AWAR_SQ_PERM "weight_iupac"
40#define AWAR_SQ_WEIGHT_GC        AWAR_SQ_PERM "weight_gc"
41
42#define AWAR_SQ_MARK_ONLY_FLAG AWAR_SQ_PERM "mark_only_flag"
43#define AWAR_SQ_MARK_FLAG      AWAR_SQ_PERM "mark_flag"
44#define AWAR_SQ_MARK_BELOW     AWAR_SQ_PERM "mark_below"
45#define AWAR_SQ_REEVALUATE     AWAR_SQ_PERM "reevaluate"
46#define AWAR_SQ_FILTER_NAME    AWAR_SQ_TEMP "filter/name"
47
48void SQ_create_awars(AW_root *aw_root, AW_default aw_def) {
49    aw_root->awar_int(AWAR_SQ_WEIGHT_BASES,     5,  aw_def);
50    aw_root->awar_int(AWAR_SQ_WEIGHT_DEVIATION, 15, aw_def);
51    aw_root->awar_int(AWAR_SQ_WEIGHT_HELIX,     15, aw_def);
52    aw_root->awar_int(AWAR_SQ_WEIGHT_CONSENSUS, 50, aw_def);
53    aw_root->awar_int(AWAR_SQ_WEIGHT_IUPAC,     5,  aw_def);
54    aw_root->awar_int(AWAR_SQ_WEIGHT_GC,        10, aw_def);
55    aw_root->awar_int(AWAR_SQ_MARK_ONLY_FLAG,   0,  aw_def);
56    aw_root->awar_int(AWAR_SQ_MARK_FLAG,        1,  aw_def);
57    aw_root->awar_int(AWAR_SQ_MARK_BELOW,       40, aw_def);
58    aw_root->awar_int(AWAR_SQ_REEVALUATE,       0,  aw_def);
59
60    awt_create_filter_awars(aw_root, aw_def, AWAR_SQ_FILTER_NAME, AWAR_DEFAULT_ALIGNMENT);
61}
62
63// --------------------------------------------------------------------------------
64
65
66inline size_t count_nodes(TreeNode *node) {
67    // calculate number of nodes in tree
68    return GBT_count_leafs(node)*2-1;
69}
70
71static void sq_calc_seq_quality_cb(AW_window * aww, adfiltercbstruct *acbs, GBDATA *gb_main) {
72    AW_root  *aw_root     = aww->get_root();
73    GB_ERROR  error       = NULp;
74    TreeNode *tree        = NULp;
75    bool      marked_only = (aw_root->awar(AWAR_SQ_MARK_ONLY_FLAG)->read_int() > 0);
76
77    arb_progress main_progress("Calculating sequence quality");
78
79    {
80        char *treename = aw_root->awar(AWAR_TREE)->read_string();
81
82        if (treename && strcmp(treename, NO_TREE_SELECTED) != 0) {
83            error = GB_push_transaction(gb_main);
84
85            if (!error) {
86                tree = GBT_read_tree(gb_main, treename, new SimpleRoot);
87                if (!tree) error = GB_await_error();
88                else {
89                    error = GBT_link_tree(tree, gb_main, false, NULp, NULp);
90                    if (!error) {
91                        GBT_TreeRemoveType mode = marked_only ? GBT_KEEP_MARKED : GBT_REMOVE_ZOMBIES;
92                        tree = GBT_remove_leafs(tree, mode, NULp, NULp, NULp);
93                        if (!tree || tree->is_leaf()) {
94                            error = GBS_global_string("Tree contains less than 2 species after removing zombies%s",
95                                                      marked_only ? " and non-marked" : "");
96                        }
97                    }
98                }
99            }
100
101            error = GB_end_transaction(gb_main, error);
102        }
103        free(treename);
104    }
105
106    // if tree == 0 -> do basic quality calculations that are possible without tree information
107    // otherwise    -> use all groups found in tree and compare sequences against the groups they are contained in
108
109    if (!error) {
110        struct SQ_weights weights;
111
112        weights.bases = aw_root->awar(AWAR_SQ_WEIGHT_BASES)->read_int();
113        weights.diff_from_average = aw_root->awar(AWAR_SQ_WEIGHT_DEVIATION)->read_int();
114        weights.helix = aw_root->awar(AWAR_SQ_WEIGHT_HELIX)->read_int();
115        weights.consensus = aw_root->awar(AWAR_SQ_WEIGHT_CONSENSUS)->read_int();
116        weights.iupac = aw_root->awar(AWAR_SQ_WEIGHT_IUPAC)->read_int();
117        weights.gc = aw_root->awar(AWAR_SQ_WEIGHT_GC)->read_int();
118
119        int mark_flag = aw_root->awar(AWAR_SQ_MARK_FLAG)->read_int();
120        int mark_below = aw_root->awar(AWAR_SQ_MARK_BELOW)->read_int();
121        int reevaluate = aw_root->awar(AWAR_SQ_REEVALUATE)->read_int();
122
123        // Load and use Sequence-Filter
124        AP_filter *filter = awt_get_filter(acbs);
125        error             = awt_invalid_filter(filter);
126
127        /*
128          SQ_evaluate() generates the final estimation for the quality of an alignment.
129          It takes the values from the different containers, which are generated by the other functions, weights them
130          and calculates a final value. The final value is stored in "value_of_evaluation" (see options).
131          With the values stored in "weights" one can customize how important a value stored in a container becomes
132          for the final result.
133        */
134
135        if (!error) {
136            if (!tree) {
137                if (reevaluate) {
138                    SQ_mark_species(gb_main, mark_below, marked_only);
139                }
140                else {
141                    arb_progress  progress(GBT_get_species_count(gb_main)*2);
142                    SQ_GroupData *globalData = new SQ_GroupData_RNA;
143
144                    progress.subtitle("pass1");
145                    error = SQ_pass1_no_tree(globalData, gb_main, filter, progress);
146                    if (!error) {
147                        progress.subtitle("pass2");
148                        error = SQ_pass2_no_tree(globalData, gb_main, filter, progress);
149                        if (!error) {
150                            error = SQ_evaluate(gb_main, weights, marked_only);
151                            if (mark_flag && !error) {
152                                SQ_mark_species(gb_main, mark_below, marked_only);
153                            }
154                        }
155                    }
156                    if (error) progress.done();
157                    delete globalData;
158                }
159            }
160            else {
161                SQ_TREE_ERROR check = SQ_check_tree_structure(tree);
162                if (check != NONE) {
163                    switch (check) {
164                        case ZOMBIE:
165                            error = "Found one or more zombies in the tree.\n"
166                                "Please remove them or use another tree before running the quality check tool.";
167                            break;
168                        case MISSING_NODE:
169                            error = "Missing node(s) or unusable tree structure.\n"
170                                "Please fix the tree before running the quality check tool.";
171                            break;
172                        default:
173                            error = "An error occurred while traversing the tree.\n"
174                                "Please fix the tree before running the quality check tool.";
175                            break;
176                    }
177                }
178                else if (reevaluate) {
179                    SQ_mark_species(gb_main, mark_below, marked_only);
180                }
181                else {
182                    arb_progress progress(count_nodes(tree)*2);
183                    SQ_GroupData *globalData = new SQ_GroupData_RNA;
184
185                    progress.subtitle("pass1");
186                    SQ_calc_and_apply_group_data(tree, gb_main, globalData, filter, progress);
187                    progress.subtitle("pass2");
188                    SQ_calc_and_apply_group_data2(tree, gb_main, globalData, filter, progress);
189                    SQ_evaluate(gb_main, weights, marked_only);
190                    if (mark_flag) SQ_mark_species(gb_main, mark_below, marked_only);
191                    delete globalData;
192                }
193            }
194        }
195        awt_destroy_filter(filter);
196    }
197
198    if (error) aw_message(error);
199
200    SQ_clear_group_dictionary();
201    UNCOVERED();
202    destroy(tree);
203}
204
205static void sq_remove_quality_entries_cb(AW_window*, GBDATA *gb_main) {
206    GB_ERROR error = SQ_remove_quality_entries(gb_main);
207    aw_message_if(error);
208}
209
210static AWT_config_mapping_def seq_quality_config_mapping[] = {
211    { AWAR_SQ_WEIGHT_BASES,     "wbases" },
212    { AWAR_SQ_WEIGHT_DEVIATION, "wdeviation" },
213    { AWAR_SQ_WEIGHT_HELIX,     "whelix" },
214    { AWAR_SQ_WEIGHT_CONSENSUS, "wconsens" },
215    { AWAR_SQ_WEIGHT_IUPAC,     "wiupac" },
216    { AWAR_SQ_WEIGHT_GC,        "wgc" },
217    { AWAR_SQ_MARK_ONLY_FLAG,   "onlymarked" },
218    { AWAR_SQ_MARK_FLAG,        "markbad" },
219    { AWAR_SQ_MARK_BELOW,       "markbelow" },
220    { AWAR_SQ_REEVALUATE,       "reeval" },
221
222    { NULp, NULp }
223};
224
225AW_window *SQ_create_seq_quality_window(AW_root *aw_root, GBDATA *gb_main) {
226    // create window for sequence quality calculation (called only once)
227
228    AW_window_simple *aws = new AW_window_simple;
229
230    aws->init(aw_root, "CALC_SEQ_QUALITY", "CALCULATE SEQUENCE QUALITY");
231    aws->load_xfig("seq_quality.fig");
232
233    aws->at("close");
234    aws->callback(AW_POPDOWN);
235    aws->create_button("CLOSE", "CLOSE", "C");
236
237    aws->at("help");
238    aws->callback(makeHelpCallback("seq_quality.hlp"));
239    aws->create_button("HELP", "HELP", "H");
240
241    aws->at("base");
242    aws->create_input_field(AWAR_SQ_WEIGHT_BASES, 3);
243
244    aws->at("deviation");
245    aws->create_input_field(AWAR_SQ_WEIGHT_DEVIATION, 3);
246
247    aws->at("no_helices");
248    aws->create_input_field(AWAR_SQ_WEIGHT_HELIX, 3);
249
250    aws->at("consensus");
251    aws->create_input_field(AWAR_SQ_WEIGHT_CONSENSUS, 3);
252
253    aws->at("iupac");
254    aws->create_input_field(AWAR_SQ_WEIGHT_IUPAC, 3);
255
256    aws->at("gc_proportion");
257    aws->create_input_field(AWAR_SQ_WEIGHT_GC, 3);
258
259    aws->at("monly");
260    aws->create_toggle(AWAR_SQ_MARK_ONLY_FLAG);
261
262    aws->at("mark");
263    aws->create_toggle(AWAR_SQ_MARK_FLAG);
264
265    aws->at("mark_below");
266    aws->create_input_field(AWAR_SQ_MARK_BELOW, 3);
267
268    aws->at("tree");
269    awt_create_TREE_selection_list(gb_main, aws, AWAR_TREE, true);
270
271    aws->at("filter");
272    adfiltercbstruct *adfilter = awt_create_select_filter(aws->get_root(), gb_main, AWAR_SQ_FILTER_NAME);
273    aws->callback(makeCreateWindowCallback(awt_create_select_filter_win, adfilter));
274    aws->create_button("SELECT_FILTER", AWAR_SQ_FILTER_NAME);
275
276    aws->at("go");
277    aws->callback(makeWindowCallback(sq_calc_seq_quality_cb, adfilter, gb_main));
278    aws->highlight();
279    aws->create_button("GO", "GO", "G");
280
281    aws->at("config");
282    AWT_insert_config_manager(aws, AW_ROOT_DEFAULT, "seq_quality", seq_quality_config_mapping);
283
284    aws->at("reevaluate");
285    aws->label("Re-Evaluate only");
286    aws->create_toggle(AWAR_SQ_REEVALUATE);
287
288    aws->at("remove");
289    aws->callback(makeWindowCallback(sq_remove_quality_entries_cb, gb_main));
290    aws->create_button("Remove", "Remove", "R");
291
292    return aws;
293}
Note: See TracBrowser for help on using the repository browser.