| 1 | #ifndef ARBDBT_H |
|---|
| 2 | #define ARBDBT_H |
|---|
| 3 | |
|---|
| 4 | #ifndef ARBDB_H |
|---|
| 5 | #include <arbdb.h> |
|---|
| 6 | #endif |
|---|
| 7 | #ifndef DOWNCAST_H |
|---|
| 8 | #include <downcast.h> |
|---|
| 9 | #endif |
|---|
| 10 | |
|---|
| 11 | #define gb_assert(cond) arb_assert(cond) |
|---|
| 12 | |
|---|
| 13 | #define GBT_SPECIES_INDEX_SIZE 10000L |
|---|
| 14 | #define GBT_SAI_INDEX_SIZE 1000L |
|---|
| 15 | |
|---|
| 16 | #define GB_GROUP_NAME_MAX 256 |
|---|
| 17 | |
|---|
| 18 | #define DEFAULT_BRANCH_LENGTH 0.1 |
|---|
| 19 | |
|---|
| 20 | #define ERROR_CONTAINER_PATH "tmp/message/pending" |
|---|
| 21 | |
|---|
| 22 | #define REMOTE_BASE "tmp/remote/" |
|---|
| 23 | #define MACRO_TRIGGER_CONTAINER REMOTE_BASE "trigger" |
|---|
| 24 | #define MACRO_TRIGGER_TERMINATED MACRO_TRIGGER_CONTAINER "/terminated" |
|---|
| 25 | #define MACRO_TRIGGER_RECORDING MACRO_TRIGGER_CONTAINER "/recording" |
|---|
| 26 | #define MACRO_TRIGGER_ERROR MACRO_TRIGGER_CONTAINER "/error" |
|---|
| 27 | #define MACRO_TRIGGER_TRACKED MACRO_TRIGGER_CONTAINER "/tracked" |
|---|
| 28 | |
|---|
| 29 | #define DEFINE_SIMPLE_TREE_RELATIVES_ACCESSORS(TreeType) \ |
|---|
| 30 | DEFINE_DOWNCAST_ACCESSORS(TreeType, get_father, father); \ |
|---|
| 31 | DEFINE_DOWNCAST_ACCESSORS(TreeType, get_leftson, leftson); \ |
|---|
| 32 | DEFINE_DOWNCAST_ACCESSORS(TreeType, get_rightson, rightson) |
|---|
| 33 | |
|---|
| 34 | enum GBT_RemarkType { REMARK_NONE, REMARK_BOOTSTRAP, REMARK_OTHER }; |
|---|
| 35 | |
|---|
| 36 | struct GBT_TREE : virtual Noncopyable { |
|---|
| 37 | bool is_leaf; |
|---|
| 38 | GBT_TREE *father, *leftson, *rightson; |
|---|
| 39 | GBT_LEN leftlen, rightlen; |
|---|
| 40 | GBDATA *gb_node; |
|---|
| 41 | char *name; |
|---|
| 42 | |
|---|
| 43 | private: |
|---|
| 44 | char *remark_branch; // remark_branch normally contains some bootstrap value in format 'xx%' |
|---|
| 45 | // if you store other info there, please make sure that this info does not start with digits!! |
|---|
| 46 | // Otherwise the tree export routines will not work correctly! |
|---|
| 47 | |
|---|
| 48 | GBT_LEN& length_ref() { return is_leftson() ? father->leftlen : father->rightlen; } |
|---|
| 49 | const GBT_LEN& length_ref() const { return const_cast<GBT_TREE*>(this)->length_ref(); } |
|---|
| 50 | |
|---|
| 51 | protected: |
|---|
| 52 | GBT_TREE*& self_ref() { |
|---|
| 53 | return is_leftson() ? father->leftson : father->rightson; |
|---|
| 54 | } |
|---|
| 55 | void unlink_from_father() { |
|---|
| 56 | if (father) { |
|---|
| 57 | self_ref() = NULL; |
|---|
| 58 | father = NULL; |
|---|
| 59 | } |
|---|
| 60 | } |
|---|
| 61 | |
|---|
| 62 | char *swap_remark(char *new_remark) { |
|---|
| 63 | char *result = remark_branch; |
|---|
| 64 | remark_branch = new_remark; |
|---|
| 65 | return result; |
|---|
| 66 | } |
|---|
| 67 | |
|---|
| 68 | public: |
|---|
| 69 | GBT_TREE() |
|---|
| 70 | : is_leaf(false), |
|---|
| 71 | father(NULL), leftson(NULL), rightson(NULL), |
|---|
| 72 | leftlen(0.0), rightlen(0.0), |
|---|
| 73 | gb_node(NULL), |
|---|
| 74 | name(NULL), |
|---|
| 75 | remark_branch(NULL) |
|---|
| 76 | {} |
|---|
| 77 | virtual ~GBT_TREE() { |
|---|
| 78 | delete leftson; gb_assert(!leftson); |
|---|
| 79 | delete rightson; gb_assert(!rightson); |
|---|
| 80 | |
|---|
| 81 | unlink_from_father(); |
|---|
| 82 | |
|---|
| 83 | free(name); |
|---|
| 84 | free(remark_branch); |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | DEFINE_SIMPLE_TREE_RELATIVES_ACCESSORS(GBT_TREE); |
|---|
| 88 | |
|---|
| 89 | virtual void announce_tree_constructed() { |
|---|
| 90 | // (has to be) called after tree has been constructed |
|---|
| 91 | gb_assert(!father); // has to be called with root-node! |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | bool is_son_of(const GBT_TREE *Father) const { |
|---|
| 95 | return father == Father && |
|---|
| 96 | (father->leftson == this || father->rightson == this); |
|---|
| 97 | } |
|---|
| 98 | bool is_leftson() const { |
|---|
| 99 | gb_assert(is_son_of(get_father())); // do only call with sons! |
|---|
| 100 | return father->leftson == this; |
|---|
| 101 | } |
|---|
| 102 | bool is_rightson() const { |
|---|
| 103 | gb_assert(is_son_of(get_father())); // do only call with sons! |
|---|
| 104 | return father->rightson == this; |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | bool is_root_node() const { return !father; } |
|---|
| 108 | |
|---|
| 109 | bool is_inside(const GBT_TREE *subtree) const { |
|---|
| 110 | return this == subtree || (father && get_father()->is_inside(subtree)); |
|---|
| 111 | } |
|---|
| 112 | bool is_anchestor_of(const GBT_TREE *descendant) const { |
|---|
| 113 | return !is_leaf && descendant != this && descendant->is_inside(this); |
|---|
| 114 | } |
|---|
| 115 | const GBT_TREE *ancestor_common_with(const GBT_TREE *other) const; |
|---|
| 116 | GBT_TREE *ancestor_common_with(GBT_TREE *other) { return const_cast<GBT_TREE*>(ancestor_common_with(other)); } |
|---|
| 117 | |
|---|
| 118 | GBT_TREE *fixDeletedSon(); |
|---|
| 119 | |
|---|
| 120 | GBT_LEN get_branchlength() const { return length_ref(); } |
|---|
| 121 | void set_branchlength(GBT_LEN newlen) { |
|---|
| 122 | gb_assert(!is_nan_or_inf(newlen)); |
|---|
| 123 | length_ref() = newlen; |
|---|
| 124 | } |
|---|
| 125 | |
|---|
| 126 | GBT_LEN get_branchlength_unrooted() const { |
|---|
| 127 | //! like get_branchlength, but root-edge is treated correctly |
|---|
| 128 | if (father->is_root_node()) { |
|---|
| 129 | return father->leftlen+father->rightlen; |
|---|
| 130 | } |
|---|
| 131 | return get_branchlength(); |
|---|
| 132 | } |
|---|
| 133 | void set_branchlength_unrooted(GBT_LEN newlen) { |
|---|
| 134 | //! like set_branchlength, but root-edge is treated correctly |
|---|
| 135 | if (father->is_root_node()) { |
|---|
| 136 | father->leftlen = father->rightlen = newlen/2; |
|---|
| 137 | } |
|---|
| 138 | else { |
|---|
| 139 | set_branchlength(newlen); |
|---|
| 140 | } |
|---|
| 141 | } |
|---|
| 142 | |
|---|
| 143 | GBT_LEN sum_child_lengths() const; |
|---|
| 144 | GBT_LEN root_distance() const { |
|---|
| 145 | //! returns distance from node to root (including nodes own length) |
|---|
| 146 | return father ? get_branchlength()+father->root_distance() : 0.0; |
|---|
| 147 | } |
|---|
| 148 | GBT_LEN intree_distance_to(const GBT_TREE *other) const { |
|---|
| 149 | const GBT_TREE *ancestor = ancestor_common_with(other); |
|---|
| 150 | return root_distance() + other->root_distance() - 2*ancestor->root_distance(); |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | enum bs100_mode { BS_UNDECIDED, BS_REMOVE, BS_INSERT }; |
|---|
| 154 | bs100_mode toggle_bootstrap100(bs100_mode mode = BS_UNDECIDED); // toggle bootstrap '100%' <-> '' |
|---|
| 155 | void remove_bootstrap(); // remove bootstrap values from subtree |
|---|
| 156 | |
|---|
| 157 | void reset_branchlengths(); // reset branchlengths of subtree to tree_defaults::LENGTH |
|---|
| 158 | void scale_branchlengths(double factor); |
|---|
| 159 | |
|---|
| 160 | void bootstrap2branchlen(); // copy bootstraps to branchlengths |
|---|
| 161 | void branchlen2bootstrap(); // copy branchlengths to bootstraps |
|---|
| 162 | |
|---|
| 163 | GBT_RemarkType parse_bootstrap(double& bootstrap) const { |
|---|
| 164 | /*! analyse 'remark_branch' and return GBT_RemarkType. |
|---|
| 165 | * If result is REMARK_BOOTSTRAP, 'bootstrap' contains the bootstrap value |
|---|
| 166 | */ |
|---|
| 167 | if (!remark_branch) return REMARK_NONE; |
|---|
| 168 | |
|---|
| 169 | const char *end = 0; |
|---|
| 170 | bootstrap = strtod(remark_branch, (char**)&end); |
|---|
| 171 | |
|---|
| 172 | bool is_bootstrap = end[0] == '%' && end[1] == 0; |
|---|
| 173 | return is_bootstrap ? REMARK_BOOTSTRAP : REMARK_OTHER; |
|---|
| 174 | } |
|---|
| 175 | const char *get_remark() const { return remark_branch; } |
|---|
| 176 | void use_as_remark(char *newRemark) { freeset(remark_branch, newRemark); } |
|---|
| 177 | void set_remark(const char *newRemark) { freedup(remark_branch, newRemark); } |
|---|
| 178 | void set_bootstrap(double bootstrap) { use_as_remark(GBS_global_string_copy("%i%%", int(bootstrap+0.5))); } // @@@ protect against "100%"? |
|---|
| 179 | void remove_remark() { use_as_remark(NULL); } |
|---|
| 180 | }; |
|---|
| 181 | |
|---|
| 182 | struct TreeNodeFactory { |
|---|
| 183 | virtual ~TreeNodeFactory() {} |
|---|
| 184 | virtual GBT_TREE *makeNode() const = 0; |
|---|
| 185 | }; |
|---|
| 186 | |
|---|
| 187 | struct GBT_TREE_NodeFactory : public TreeNodeFactory { |
|---|
| 188 | GBT_TREE *makeNode() const OVERRIDE { return new GBT_TREE; } |
|---|
| 189 | }; |
|---|
| 190 | |
|---|
| 191 | enum GBT_TreeRemoveType { |
|---|
| 192 | GBT_REMOVE_MARKED = 1, |
|---|
| 193 | GBT_REMOVE_UNMARKED = 2, |
|---|
| 194 | GBT_REMOVE_ZOMBIES = 4, |
|---|
| 195 | |
|---|
| 196 | // please keep AWT_RemoveType in sync with GBT_TreeRemoveType |
|---|
| 197 | // see ../SL/AP_TREE/AP_Tree.hxx@sync_GBT_TreeRemoveType__AWT_RemoveType |
|---|
| 198 | |
|---|
| 199 | // combined defines: |
|---|
| 200 | GBT_KEEP_MARKED = GBT_REMOVE_UNMARKED|GBT_REMOVE_ZOMBIES, |
|---|
| 201 | }; |
|---|
| 202 | |
|---|
| 203 | enum GBT_ORDER_MODE { |
|---|
| 204 | GBT_BEHIND, |
|---|
| 205 | GBT_INFRONTOF, |
|---|
| 206 | }; |
|---|
| 207 | |
|---|
| 208 | enum TreeModel { ROOTED = 0, UNROOTED = 1 }; |
|---|
| 209 | |
|---|
| 210 | inline CONSTEXPR_RETURN int nodes_2_edges(int nodes) { return nodes-1; } |
|---|
| 211 | inline CONSTEXPR_RETURN int edges_2_nodes(int nodes) { return nodes+1; } |
|---|
| 212 | |
|---|
| 213 | inline CONSTEXPR_RETURN int leafs_2_nodes(int leafs, TreeModel model) { |
|---|
| 214 | //! calculate the number of nodes (leaf- plus inner-nodes) in a tree with 'leafs' leafs |
|---|
| 215 | return 2*leafs-1-int(model); |
|---|
| 216 | } |
|---|
| 217 | inline CONSTEXPR_RETURN int nodes_2_leafs(int nodes, TreeModel model) { |
|---|
| 218 | //! calculate the number of leafs in a tree with 'nodes' nodes |
|---|
| 219 | return (nodes+1+int(model))/2; |
|---|
| 220 | } |
|---|
| 221 | inline CONSTEXPR_RETURN int leafs_2_edges(int leafs, TreeModel model) { |
|---|
| 222 | //! calculate the number of edges in a tree with 'leafs' leafs |
|---|
| 223 | return nodes_2_edges(leafs_2_nodes(leafs, model)); |
|---|
| 224 | } |
|---|
| 225 | inline CONSTEXPR_RETURN int edges_2_leafs(int edges, TreeModel model) { |
|---|
| 226 | //! calculate the number of leafs in a tree with 'edges' edges |
|---|
| 227 | return nodes_2_leafs(edges_2_nodes(edges), model); |
|---|
| 228 | } |
|---|
| 229 | |
|---|
| 230 | #define GBT_TREE_AWAR_SRT " = :\n=:*=tree_*1:tree_tree_*=tree_*1" |
|---|
| 231 | #define GBT_ALI_AWAR_SRT " =:\n=:*=ali_*1:ali_ali_*=ali_*1" |
|---|
| 232 | |
|---|
| 233 | typedef GB_ERROR (*species_callback)(GBDATA *gb_species, int *clientdata); |
|---|
| 234 | |
|---|
| 235 | #include <ad_t_prot.h> |
|---|
| 236 | |
|---|
| 237 | #define CHANGE_KEY_PATH "presets/key_data" |
|---|
| 238 | #define CHANGE_KEY_PATH_GENES "presets/gene_key_data" |
|---|
| 239 | #define CHANGE_KEY_PATH_EXPERIMENTS "presets/experiment_key_data" |
|---|
| 240 | |
|---|
| 241 | #define CHANGEKEY "key" |
|---|
| 242 | #define CHANGEKEY_NAME "key_name" |
|---|
| 243 | #define CHANGEKEY_TYPE "key_type" |
|---|
| 244 | #define CHANGEKEY_HIDDEN "key_hidden" |
|---|
| 245 | |
|---|
| 246 | |
|---|
| 247 | #else |
|---|
| 248 | #error arbdbt.h included twice |
|---|
| 249 | #endif |
|---|
| 250 | |
|---|
| 251 | |
|---|