ARB
ARB_Tree.cxx
Go to the documentation of this file.
1 // =============================================================== //
2 // //
3 // File : ARB_Tree.cxx //
4 // Purpose : Tree types with sequence knowledge //
5 // //
6 // Coded by Ralf Westram (coder@reallysoft.de) in October 2009 //
7 // Institute of Microbiology (Technical University Munich) //
8 // http://www.arb-home.de/ //
9 // //
10 // =============================================================== //
11 
12 #include "ARB_Tree.hxx"
13 
14 #include <AP_filter.hxx>
15 
16 #include <ad_cb.h>
17 
18 using namespace std;
19 
20 // --------------------------
21 // ARB_seqtree_root
22 
23 static void tree_deleted_cbwrapper(GBDATA *gb_tree, ARB_seqtree_root *troot) {
24  troot->tree_deleted_cb(gb_tree);
25 }
26 
27 
28 ARB_seqtree_root::ARB_seqtree_root(AliView *aliView, AP_sequence *seqTempl, bool add_delete_callbacks)
29  : TreeRoot(false),
30  ali(aliView),
31  seqTemplate(seqTempl ? seqTempl->dup() : NULp),
32  tree_name(NULp),
33  gb_tree(NULp),
34  isLinkedToDB(false),
35  addDeleteCallbacks(add_delete_callbacks)
36 {
37 #if defined(DEBUG)
38  at_assert(ali);
39  if (seqTemplate) {
40  at_assert(ali->has_data());
41  at_assert(seqTemplate->get_aliview() == ali);
42  }
43  else {
44  at_assert(!ali->has_data());
45  }
46 #endif // DEBUG
47 }
48 
50  delete ali;
51  delete seqTemplate;
52 
53  if (gb_tree) GB_remove_callback(gb_tree, GB_CB_DELETE, makeDatabaseCallback(tree_deleted_cbwrapper, this));
54  free(tree_name);
55 }
56 
58  if (gb_tree == gb_tree_del) { // ok - it's my tree
59  gb_tree = NULp;
60  freenull(tree_name);
61  }
62  else {
63  at_assert(0); // callback for wrong tree received
64  }
65 }
69 
70  if (!error) {
71  ARB_seqtree *old_root = get_root_node();
72  if (old_root) {
73  change_root(old_root, NULp);
74  delete old_root;
75  }
76 
77  if (gb_tree) {
78  GB_remove_callback(gb_tree, GB_CB_DELETE, makeDatabaseCallback(tree_deleted_cbwrapper, this));
79  gb_tree = NULp;
80  freenull(tree_name);
81  }
82 
83  ARB_seqtree *arb_tree = DOWNCAST(ARB_seqtree*, GBT_read_tree(gb_main, name, this));
84  if (!arb_tree) error = GB_await_error();
85  else {
86  gb_tree = GBT_find_tree(gb_main, name);
87  if (!gb_tree) error = GB_await_error();
88  else {
89  error = GB_add_callback(gb_tree, GB_CB_DELETE, makeDatabaseCallback(tree_deleted_cbwrapper, this));
90  if (!error) {
91  at_assert(arb_tree == arb_tree->get_root_node());
92  at_assert(arb_tree == get_root_node());
93  tree_name = strdup(name);
94  isLinkedToDB = false;
95  }
96  else {
97  gb_tree = NULp;
98  }
99  }
100  if (error) delete arb_tree;
101  }
102  }
103 
104  return GB_end_transaction(gb_main, error);
105 }
106 
108  GB_ERROR error;
109  if (!gb_tree) {
110  error = "Can't save your tree (no tree loaded or tree has been deleted)";
111  }
112  else {
114  error = GB_push_transaction(gb_main);
115  at_assert(get_root_node());
116  if (!error) error = GBT_overwrite_tree(gb_tree, get_root_node());
117  error = GB_end_transaction(gb_main, error);
118  }
119  return error;
120 }
121 
122 static void arb_tree_species_deleted_cb(GBDATA *gb_species, ARB_seqtree *arb_tree) {
123  // called whenever a species (which is linked to tree) gets deleted
124  at_assert(arb_tree->gb_node == gb_species);
125  if (arb_tree->gb_node == gb_species) {
126  arb_tree->gb_node = NULp; // unlink from tree
127  }
128 }
129 
130 GB_ERROR ARB_seqtree_root::linkToDB(int *zombies, int *duplicates) {
131  at_assert(!ali->has_data() || get_seqTemplate()); // if ali has data, you have to set_seqTemplate() before linking
132 
133  GB_ERROR error = NULp;
134  if (!isLinkedToDB) {
135  error = GBT_link_tree(get_root_node(), get_gb_main(), false, zombies, duplicates);
136  if (!error && addDeleteCallbacks) {
137  error = get_root_node()->add_delete_cb_rec(arb_tree_species_deleted_cb);
138  }
139  if (!error && ali->has_data() && seqTemplate) {
140  error = get_root_node()->preloadLeafSequences();
141  }
142  if (!error) isLinkedToDB = true;
143  }
144  return error;
145 }
146 
148  if (isLinkedToDB) {
149  if (addDeleteCallbacks) get_root_node()->remove_delete_cb_rec(arb_tree_species_deleted_cb);
150  GBT_unlink_tree(get_root_node());
151  if (ali->has_data() && seqTemplate) get_root_node()->unloadSequences();
152  isLinkedToDB = false;
153  }
154 }
155 
156 // ----------------------
157 // ARB_tree_info
158 
160  memset(this, 0, sizeof(*this));
161 }
162 
164  if (is_leaf()) {
165  info.leafs++;
166  if (gb_node) {
167  if (GB_read_flag(gb_node)) info.marked++;
168  }
169  else {
170  info.unlinked++;
171  }
172  }
173  else {
174  info.innerNodes++;
175  if (gb_node) info.groups++;
176  get_leftson()->calcTreeInfo(info);
177  get_rightson()->calcTreeInfo(info);
178  }
179 }
180 
181 // ---------------------
182 // ARB_seqtree
183 
185  delete seq;
186 }
187 
189  if (is_leaf()) {
190  if (gb_node) GB_write_flag(gb_node, 1);
191  }
192  else {
193  get_leftson()->mark_subtree();
194  get_rightson()->mark_subtree();
195  }
196 }
197 
199  if (is_leaf()) {
200  return gb_node && GB_read_flag(gb_node) != 0;
201  }
202  return
203  get_leftson()->contains_marked_species() ||
204  get_rightson()->contains_marked_species();
205 }
206 
207 GB_ERROR ARB_seqtree::add_delete_cb_rec(ARB_tree_node_del_cb cb) {
208  GB_ERROR error = NULp;
209  if (is_leaf()) {
210  if (gb_node) {
211  error = GB_add_callback(gb_node, GB_CB_DELETE, makeDatabaseCallback(cb, this));
212  }
213  }
214  else {
215  error = get_leftson() ->add_delete_cb_rec(cb);
216  if (error) error = get_rightson()->add_delete_cb_rec(cb);
217  }
218  return error;
219 }
220 
221 void ARB_seqtree::remove_delete_cb_rec(ARB_tree_node_del_cb cb) {
222  if (is_leaf()) {
223  if (gb_node) GB_remove_callback(gb_node, GB_CB_DELETE, makeDatabaseCallback(cb, this));
224  }
225  else {
226  get_leftson() ->remove_delete_cb_rec(cb);
227  get_rightson()->remove_delete_cb_rec(cb);
228  }
229 
230 }
231 
232 GB_ERROR ARB_seqtree::preloadLeafSequences() {
233  GB_ERROR error = NULp;
234  if (is_leaf()) {
235  if (gb_node) {
236  seq = get_tree_root()->get_seqTemplate()->dup();
237  error = seq->bind_to_species(gb_node); // does not load sequences yet
238  }
239  }
240  else {
241  error = get_leftson()->preloadLeafSequences();
242  if (!error) error = get_rightson()->preloadLeafSequences();
243  }
244  return error;
245 }
246 
247 void ARB_seqtree::unloadSequences() {
248  delete seq;
249  seq = NULp;
250  if (!is_leaf()) {
251  get_leftson()->unloadSequences();
252  get_rightson()->unloadSequences();
253  }
254 }
255 
257  if (seq) {
258  delete seq;
259  seq = NULp;
260  }
261  set_seq(sequence);
262 }
263 
264 // ------------------------
265 // ARB_countedTree
266 
268  at_assert(is_inside(upgroup));
269 
270  size_t pos = 0;
271  if (this != upgroup) {
272  pos = is_upper_son() ? 0 : get_brother()->get_leaf_count();
273  pos += get_father()->relative_position_in(upgroup);
274  }
275  return pos;
276 }
277 
GBDATA * get_gb_main() const
Definition: ARB_Tree.hxx:80
const char * GB_ERROR
Definition: arb_core.h:25
size_t marked
Definition: ARB_Tree.hxx:109
bool has_data() const
Definition: AliView.hxx:50
void GBT_unlink_tree(TreeNode *tree)
Definition: adtree.cxx:940
const TreeNode * get_root_node() const
Definition: TreeNode.h:382
GB_ERROR GB_add_callback(GBDATA *gbd, GB_CB_TYPE type, const DatabaseCallback &dbcb)
Definition: ad_cb.cxx:356
bool is_upper_son() const
Definition: ARB_Tree.hxx:159
size_t groups
Definition: ARB_Tree.hxx:107
GB_ERROR GB_end_transaction(GBDATA *gbd, GB_ERROR error)
Definition: arbdb.cxx:2549
size_t unlinked
Definition: ARB_Tree.hxx:108
TreeRoot * get_tree_root() const
Definition: TreeNode.h:380
TreeNode * GBT_read_tree(GBDATA *gb_main, const char *tree_name, TreeRoot *troot)
Definition: adtree.cxx:791
void calcTreeInfo(ARB_tree_info &info)
Definition: ARB_Tree.cxx:163
STL namespace.
ARB_seqtree_root(AliView *aliView, AP_sequence *seqTempl, bool add_delete_callbacks)
Definition: ARB_Tree.cxx:28
#define at_assert(cond)
Definition: ARB_Tree.hxx:29
GB_ERROR GBT_link_tree(TreeNode *tree, GBDATA *gb_main, bool show_status, int *zombies, int *duplicates)
Definition: adtree.cxx:907
GB_ERROR GB_push_transaction(GBDATA *gbd)
Definition: arbdb.cxx:2482
#define cb(action)
#define DOWNCAST(totype, expr)
Definition: downcast.h:141
size_t leafs
Definition: ARB_Tree.hxx:105
POS_TREE1 * get_father() const
Definition: probe_tree.h:49
GB_ERROR GB_await_error()
Definition: arb_msg.cxx:353
size_t relative_position_in(const ARB_countedTree *upgroup) const
Definition: ARB_Tree.cxx:267
GB_ERROR GBT_overwrite_tree(GBDATA *gb_tree, TreeNode *tree)
Definition: adtree.cxx:480
void replace_seq(AP_sequence *sequence)
Definition: ARB_Tree.cxx:256
virtual GB_ERROR saveToDB() __ATTR__USERESULT
Definition: ARB_Tree.cxx:107
virtual GB_ERROR loadFromDB(const char *name) __ATTR__USERESULT
Definition: ARB_Tree.cxx:66
~ARB_seqtree() OVERRIDE
Definition: ARB_Tree.cxx:184
void unlinkFromDB()
Definition: ARB_Tree.cxx:147
#define false
Definition: ureadseq.h:13
size_t innerNodes
Definition: ARB_Tree.hxx:106
static void error(const char *msg)
Definition: mkptypes.cxx:96
AP_sequence * set_seq(AP_sequence *sequence)
Definition: ARB_Tree.hxx:164
TreeNode * get_brother()
Definition: TreeNode.h:394
virtual unsigned get_leaf_count() const =0
int GB_read_flag(GBDATA *gbd)
Definition: arbdb.cxx:2784
~ARB_seqtree_root() OVERRIDE
Definition: ARB_Tree.cxx:49
static void tree_deleted_cbwrapper(GBDATA *gb_tree, ARB_seqtree_root *troot)
Definition: ARB_Tree.cxx:23
const AliView * get_aliview() const
Definition: AP_sequence.hxx:82
bool is_leaf() const
Definition: TreeNode.h:171
void GB_write_flag(GBDATA *gbd, long flag)
Definition: arbdb.cxx:2761
static void arb_tree_species_deleted_cb(GBDATA *gb_species, ARB_seqtree *arb_tree)
Definition: ARB_Tree.cxx:122
bool is_inside(const TreeNode *subtree) const
Definition: TreeNode.h:198
GB_ERROR linkToDB(int *zombies, int *duplicates) __ATTR__USERESULT
Definition: ARB_Tree.cxx:130
bool contains_marked_species()
Definition: ARB_Tree.cxx:198
void GB_remove_callback(GBDATA *gbd, GB_CB_TYPE type, const DatabaseCallback &dbcb)
Definition: ad_cb.cxx:360
#define NULp
Definition: cxxforward.h:97
void(* ARB_tree_node_del_cb)(GBDATA *, class ARB_seqtree *)
Definition: ARB_Tree.hxx:31
GBDATA * GBT_find_tree(GBDATA *gb_main, const char *tree_name)
Definition: adtree.cxx:947
GB_ERROR bind_to_species(GBDATA *gb_species)
Definition: AP_sequence.cxx:24
GBDATA * gb_node
Definition: TreeNode.h:133
GBDATA * gb_main
Definition: adname.cxx:33
virtual void change_root(TreeNode *old, TreeNode *newroot)
Definition: TreeNode.cxx:28
const AP_sequence * get_seqTemplate() const
Definition: ARB_Tree.hxx:90
void mark_subtree()
Definition: ARB_Tree.cxx:188
static int info[maxsites+1]
void tree_deleted_cb(GBDATA *gb_tree_del)
Definition: ARB_Tree.cxx:57