ARB
SQ_main.cxx
Go to the documentation of this file.
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 
48 void 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 
61 }
62 
63 // --------------------------------------------------------------------------------
64 
65 
66 inline size_t count_nodes(TreeNode *node) {
67  // calculate number of nodes in tree
68  return GBT_count_leafs(node)*2-1;
69 }
70 
72  AW_root *aw_root = aww->get_root();
74  TreeNode *tree = NULp;
75  bool marked_only = (aw_root->awar(AWAR_SQ_MARK_ONLY_FLAG)->read_int() > 0);
76  arb_progress main_progress("Calculating sequence quality");
77  GB_transaction ta(gb_main);
78 
79  if (!error) {
80  char *ali = GBT_get_default_alignment(gb_main);
81  if (ali) {
83  if (type == GB_AT_UNKNOWN) {
84  error = GB_await_error();
85  }
86  else if (type != GB_AT_RNA && type != GB_AT_DNA) {
87  error = "does only support RNA/DNA sequence data";
88  }
89  if (error) {
90  error = GBS_global_string("Invalid alignment '%s' selected (%s)", ali, error);
91  }
92  }
93  else {
94  error = "No default alignment selected";
95  }
96  free(ali);
97  }
98 
99  if (!error) {
100  char *treename = aw_root->awar(AWAR_TREE)->read_string();
101 
102  if (treename && strcmp(treename, NO_TREE_SELECTED) != 0) {
103  if (!error) {
104  tree = GBT_read_tree(gb_main, treename, new SimpleRoot);
105  if (!tree) error = GB_await_error();
106  else {
107  error = GBT_link_tree(tree, gb_main, false, NULp, NULp);
108  if (!error) {
110  tree = GBT_remove_leafs(tree, mode, NULp, NULp, NULp);
111  if (!tree || tree->is_leaf()) {
112  error = GBS_global_string("Tree contains less than 2 species after removing zombies%s",
113  marked_only ? " and non-marked" : "");
114  }
115  }
116  }
117  }
118  }
119  free(treename);
120  }
121 
122  // if tree == 0 -> do basic quality calculations that are possible without tree information
123  // otherwise -> use all groups found in tree and compare sequences against the groups they are contained in
124 
125  if (!error) {
126  struct SQ_weights weights;
127 
128  weights.bases = aw_root->awar(AWAR_SQ_WEIGHT_BASES)->read_int();
130  weights.helix = aw_root->awar(AWAR_SQ_WEIGHT_HELIX)->read_int();
131  weights.consensus = aw_root->awar(AWAR_SQ_WEIGHT_CONSENSUS)->read_int();
132  weights.iupac = aw_root->awar(AWAR_SQ_WEIGHT_IUPAC)->read_int();
133  weights.gc = aw_root->awar(AWAR_SQ_WEIGHT_GC)->read_int();
134 
135  int mark_flag = aw_root->awar(AWAR_SQ_MARK_FLAG)->read_int();
136  int mark_below = aw_root->awar(AWAR_SQ_MARK_BELOW)->read_int();
137  int reevaluate = aw_root->awar(AWAR_SQ_REEVALUATE)->read_int();
138 
139  // Load and use Sequence-Filter
140  AP_filter *filter = awt_get_filter(acbs);
141  error = awt_invalid_filter(filter);
142 
143  /*
144  SQ_evaluate() generates the final estimation for the quality of an alignment.
145  It takes the values from the different containers, which are generated by the other functions, weights them
146  and calculates a final value. The final value is stored in "value_of_evaluation" (see options).
147  With the values stored in "weights" one can customize how important a value stored in a container becomes
148  for the final result.
149  */
150 
151  if (!error) {
152  if (!tree) {
153  if (reevaluate) {
154  error = SQ_mark_species(gb_main, mark_below, marked_only);
155  }
156  else {
157  arb_progress progress(GBT_get_species_count(gb_main)*2);
158  SQ_GroupData *globalData = new SQ_GroupData_RNA;
159 
160  progress.subtitle("pass1");
161  error = SQ_pass1_no_tree(globalData, gb_main, filter, progress);
162  if (!error) {
163  progress.subtitle("pass2");
164  error = SQ_pass2_no_tree(globalData, gb_main, filter, progress);
165  if (!error) {
166  error = SQ_evaluate(gb_main, weights, marked_only);
167  if (mark_flag && !error) {
168  error = SQ_mark_species(gb_main, mark_below, marked_only);
169  }
170  }
171  }
172  if (error) progress.done();
173  delete globalData;
174  }
175  }
176  else {
178  if (check != NONE) {
179  switch (check) {
180  case ZOMBIE:
181  error = "Found one or more zombies in the tree.\n"
182  "Please remove them or use another tree before running the quality check tool.";
183  break;
184  case MISSING_NODE:
185  error = "Missing node(s) or unusable tree structure.\n"
186  "Please fix the tree before running the quality check tool.";
187  break;
188  default:
189  error = "An error occurred while traversing the tree.\n"
190  "Please fix the tree before running the quality check tool.";
191  break;
192  }
193  }
194  else if (reevaluate) {
195  error = SQ_mark_species(gb_main, mark_below, marked_only);
196  }
197  else {
198  arb_progress progress(count_nodes(tree)*2);
199  SQ_GroupData *globalData = new SQ_GroupData_RNA;
200 
201  progress.subtitle("pass1");
202  error = SQ_pass1_on_tree(tree, gb_main, globalData, filter, progress);
203  if (!error) {
204  progress.subtitle("pass2");
205  error = SQ_pass2_on_tree(tree, gb_main, globalData, filter, progress);
206  if (!error) {
207  error = SQ_evaluate(gb_main, weights, marked_only);
208  if (mark_flag && !error) {
209  error = SQ_mark_species(gb_main, mark_below, marked_only);
210  }
211  }
212  }
213  if (error) progress.done();
214  delete globalData;
215  }
216  }
217  }
218  awt_destroy_filter(filter);
219  }
220 
221  error = ta.close(error);
222  if (error) aw_message(error);
223 
225  UNCOVERED();
226  destroy(tree);
227 }
228 
231  aw_message_if(error);
232 }
233 
235  { AWAR_SQ_WEIGHT_BASES, "wbases" },
236  { AWAR_SQ_WEIGHT_DEVIATION, "wdeviation" },
237  { AWAR_SQ_WEIGHT_HELIX, "whelix" },
238  { AWAR_SQ_WEIGHT_CONSENSUS, "wconsens" },
239  { AWAR_SQ_WEIGHT_IUPAC, "wiupac" },
240  { AWAR_SQ_WEIGHT_GC, "wgc" },
241  { AWAR_SQ_MARK_ONLY_FLAG, "onlymarked" },
242  { AWAR_SQ_MARK_FLAG, "markbad" },
243  { AWAR_SQ_MARK_BELOW, "markbelow" },
244  { AWAR_SQ_REEVALUATE, "reeval" },
245 
246  { NULp, NULp }
247 };
248 
250  // create window for sequence quality calculation (called only once)
251 
252  AW_window_simple *aws = new AW_window_simple;
253 
254  aws->init(aw_root, "CALC_SEQ_QUALITY", "CALCULATE SEQUENCE QUALITY");
255  aws->load_xfig("seq_quality.fig");
256 
257  aws->at("close");
258  aws->callback(AW_POPDOWN);
259  aws->create_button("CLOSE", "CLOSE", "C");
260 
261  aws->at("help");
262  aws->callback(makeHelpCallback("seq_quality.hlp"));
263  aws->create_button("HELP", "HELP", "H");
264 
265  aws->at("base");
266  aws->create_input_field(AWAR_SQ_WEIGHT_BASES, 3);
267 
268  aws->at("deviation");
269  aws->create_input_field(AWAR_SQ_WEIGHT_DEVIATION, 3);
270 
271  aws->at("no_helices");
272  aws->create_input_field(AWAR_SQ_WEIGHT_HELIX, 3);
273 
274  aws->at("consensus");
275  aws->create_input_field(AWAR_SQ_WEIGHT_CONSENSUS, 3);
276 
277  aws->at("iupac");
278  aws->create_input_field(AWAR_SQ_WEIGHT_IUPAC, 3);
279 
280  aws->at("gc_proportion");
281  aws->create_input_field(AWAR_SQ_WEIGHT_GC, 3);
282 
283  aws->at("monly");
284  aws->create_toggle(AWAR_SQ_MARK_ONLY_FLAG);
285 
286  aws->at("mark");
287  aws->create_toggle(AWAR_SQ_MARK_FLAG);
288 
289  aws->at("mark_below");
290  aws->create_input_field(AWAR_SQ_MARK_BELOW, 3);
291 
292  aws->at("tree");
294 
295  aws->at("filter");
297  aws->callback(makeCreateWindowCallback(awt_create_select_filter_win, adfilter));
298  aws->create_button("SELECT_FILTER", AWAR_SQ_FILTER_NAME);
299 
300  aws->at("go");
301  aws->callback(makeWindowCallback(sq_calc_seq_quality_cb, adfilter, gb_main));
302  aws->highlight();
303  aws->create_button("GO", "GO", "G");
304 
305  aws->at("config");
306  AWT_insert_config_manager(aws, AW_ROOT_DEFAULT, "seq_quality", seq_quality_config_mapping);
307 
308  aws->at("reevaluate");
309  aws->label("Re-Evaluate only");
310  aws->create_toggle(AWAR_SQ_REEVALUATE);
311 
312  aws->at("remove");
313  aws->callback(makeWindowCallback(sq_remove_quality_entries_cb, gb_main));
314  aws->create_button("Remove", "Remove", "R");
315 
316  return aws;
317 }
void awt_create_filter_awars(AW_root *aw_root, AW_default aw_def, const char *awar_filtername, const char *awar_mapto_alignment)
Definition: AWT_filter.cxx:194
#define AWAR_SQ_WEIGHT_DEVIATION
Definition: SQ_main.cxx:36
const char * GB_ERROR
Definition: arb_core.h:25
#define NONE
Definition: GDE_def.h:34
size_t GBT_count_leafs(const TreeNode *tree)
Definition: adtree.cxx:842
GB_TYPES type
GBT_TreeRemoveType
Definition: arbdbt.h:31
void awt_destroy_filter(AP_filter *filter)
Definition: AWT_filter.cxx:471
void SQ_create_awars(AW_root *aw_root, AW_default aw_def)
Definition: SQ_main.cxx:48
#define AWAR_SQ_WEIGHT_GC
Definition: SQ_main.cxx:40
void load_xfig(const char *file, bool resize=true)
Definition: AW_window.cxx:720
#define AWAR_SQ_WEIGHT_CONSENSUS
Definition: SQ_main.cxx:38
TreeNode * GBT_remove_leafs(TreeNode *tree, GBT_TreeRemoveType mode, const GB_HASH *species_hash, int *removed, int *groups_removed)
Definition: adtree.cxx:34
#define NO_TREE_SELECTED
GB_ERROR SQ_pass2_on_tree(TreeNode *node, GBDATA *gb_main, const SQ_GroupData *data, AP_filter *filter, arb_progress &progress)
void AWT_insert_config_manager(AW_window *aww, AW_default default_file_, const char *id, const StoreConfigCallback &store_cb, const RestoreConfigCallback &load_or_reset_cb, const char *macro_id, const AWT_predefined_config *predef)
#define AWAR_DEFAULT_ALIGNMENT
Definition: aw_awar_defs.hxx:8
TreeNode * GBT_read_tree(GBDATA *gb_main, const char *tree_name, TreeRoot *troot)
Definition: adtree.cxx:837
long read_int() const
Definition: AW_awar.cxx:184
const char * GBS_global_string(const char *templat,...)
Definition: arb_msg.cxx:203
AW_DB_selection * awt_create_TREE_selection_list(GBDATA *gb_main, AW_window *aws, const char *varname)
void AW_POPDOWN(AW_window *window)
Definition: AW_window.cxx:52
#define AWAR_SQ_MARK_BELOW
Definition: SQ_main.cxx:44
GB_ERROR GBT_link_tree(TreeNode *tree, GBDATA *gb_main, bool show_status, int *zombies, int *duplicates)
Definition: adtree.cxx:953
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:342
WindowCallback makeHelpCallback(const char *helpfile)
Definition: aw_window.hxx:106
#define AWAR_SQ_WEIGHT_BASES
Definition: SQ_main.cxx:35
GB_ERROR SQ_mark_species(GBDATA *gb_main, int condition, bool marked_only)
GB_ERROR SQ_pass2_no_tree(const SQ_GroupData *globalData, GBDATA *gb_main, AP_filter *filter, arb_progress &progress)
void SQ_clear_group_dictionary()
#define AWAR_SQ_MARK_FLAG
Definition: SQ_main.cxx:43
static void error(const char *msg)
Definition: mkptypes.cxx:96
GB_ERROR SQ_pass1_on_tree(TreeNode *node, GBDATA *gb_main, SQ_GroupData *data, AP_filter *filter, arb_progress &progress)
#define AWAR_TREE
static void sq_remove_quality_entries_cb(AW_window *, GBDATA *gb_main)
Definition: SQ_main.cxx:229
adfiltercbstruct * awt_create_select_filter(AW_root *aw_root, GBDATA *gb_main, const char *def_name)
Definition: AWT_filter.cxx:225
GB_alignment_type GBT_get_alignment_type(GBDATA *gb_main, const char *aliname)
Definition: adali.cxx:878
AW_window * awt_create_select_filter_win(AW_root *aw_root, adfiltercbstruct *acbs)
Definition: AWT_filter.cxx:365
SQ_TREE_ERROR
Definition: SQ_functions.h:80
char * read_string() const
Definition: AW_awar.cxx:198
AW_awar * awar(const char *awar)
Definition: AW_root.cxx:554
size_t count_nodes(TreeNode *node)
Definition: SQ_main.cxx:66
GB_ERROR SQ_pass1_no_tree(SQ_GroupData *globalData, GBDATA *gb_main, AP_filter *filter, arb_progress &progress)
GB_alignment_type
Definition: arbdb_base.h:61
AP_filter * awt_get_filter(adfiltercbstruct *acbs)
Definition: AWT_filter.cxx:431
#define AWAR_SQ_REEVALUATE
Definition: SQ_main.cxx:45
#define AWAR_SQ_WEIGHT_HELIX
Definition: SQ_main.cxx:37
bool is_leaf() const
Definition: TreeNode.h:211
AW_awar * awar_int(const char *var_name, long default_value=0, AW_default default_file=AW_ROOT_DEFAULT)
Definition: AW_root.cxx:580
GB_ERROR close(GB_ERROR error)
Definition: arbdbpp.cxx:35
GB_ERROR SQ_evaluate(GBDATA *gb_main, const SQ_weights &weights, bool marked_only)
void subtitle(const char *stitle)
Definition: arb_progress.h:321
#define AWAR_SQ_FILTER_NAME
Definition: SQ_main.cxx:46
#define AWAR_SQ_MARK_ONLY_FLAG
Definition: SQ_main.cxx:42
GB_ERROR awt_invalid_filter(AP_filter *filter)
Definition: AWT_filter.cxx:467
void aw_message(const char *msg)
Definition: AW_status.cxx:1142
AW_root * get_root()
Definition: aw_window.hxx:359
#define NULp
Definition: cxxforward.h:116
SQ_TREE_ERROR SQ_check_tree_structure(TreeNode *node)
static void sq_calc_seq_quality_cb(AW_window *aww, adfiltercbstruct *acbs, GBDATA *gb_main)
Definition: SQ_main.cxx:71
char * GBT_get_default_alignment(GBDATA *gb_main)
Definition: adali.cxx:747
long GBT_get_species_count(GBDATA *gb_main)
Definition: aditem.cxx:207
GB_transaction ta(gb_var)
void destroy(TreeNode *that)
Definition: TreeNode.h:600
GBDATA * gb_main
Definition: adname.cxx:32
static AWT_config_mapping_def seq_quality_config_mapping[]
Definition: SQ_main.cxx:234
int diff_from_average
Definition: SQ_functions.h:59
GB_ERROR SQ_remove_quality_entries(GBDATA *gb_main)
#define AW_ROOT_DEFAULT
Definition: aw_base.hxx:106
#define AWAR_SQ_WEIGHT_IUPAC
Definition: SQ_main.cxx:39
AW_window * SQ_create_seq_quality_window(AW_root *aw_root, GBDATA *gb_main)
Definition: SQ_main.cxx:249
void aw_message_if(GB_ERROR error)
Definition: aw_msg.hxx:21
#define UNCOVERED()
Definition: arb_assert.h:380