-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTreeNode.h
192 lines (162 loc) · 4.65 KB
/
TreeNode.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#ifndef TREENODE_H
#define TREENODE_H
#include <string>
#include <vector>
#include "MatrixSize.h"
/// Phylogenetic tree node representation
///
/// @author Mario Valle - Swiss National Supercomputing Centre (CSCS)
/// @date 2010-08-31 (initial version)
/// @version 1.1
///
class TreeNode {
public:
/// Constructor.
///
TreeNode() : mParent(NULL), mBranchLength(0.) {}
/// Destructor.
///
~TreeNode() {
mChildrenList.clear();
mNodeName.clear();
mNodeMark.clear();
}
/// Copy constructor
///
/// @param[in] aNode Node that has to be assigned to the current node
///
TreeNode(const TreeNode &aNode)
: mParent(aNode.getParent()), mBranchLength(aNode.getLen()),
mNodeName(aNode.getLabel()), mNodeMark(aNode.getType()) {
for (unsigned int i = 0;; ++i) {
TreeNode *n = getChild(i);
if (!n)
break;
mChildrenList.push_back(n);
}
}
/// Assignment operator
///
/// @param[in] aNode Node that has to be assigned to the current node
///
/// @return The node itself
///
TreeNode &operator=(const TreeNode &aNode) {
// Make sure not same object
if (this != &aNode) {
mParent = aNode.getParent();
for (unsigned int i = 0;; ++i) {
TreeNode *n = getChild(i);
if (!n)
break;
mChildrenList.push_back(n);
}
mNodeName = aNode.getLabel();
mNodeMark = aNode.getType();
mBranchLength = aNode.getLen();
}
// Return ref for multiple assignment
return *this;
}
/// Add the node label.
///
/// @param[in] aLabel The node label
///
void addLabel(const std::string &aLabel) { mNodeName = aLabel; }
/// Add the node type (the string after the '#' symbol in label).
///
/// @param[in] aMark The node type string
///
void addType(const std::string &aMark) { mNodeMark = aMark; }
/// Add the branch length.
///
/// @param[in] aBranchLength The branch length
///
void addLen(double aBranchLength) { mBranchLength = aBranchLength; }
/// Add a child to the node.
///
/// @param[in] aNode The child node
///
void addChild(TreeNode *aNode) { mChildrenList.push_back(aNode); }
/// Add the node parent.
///
/// @param[in] aNode The node parent
///
void addParent(TreeNode *aNode) { mParent = aNode; }
/// Print the node info indented by the amount requested.
///
/// @param[in] aIndent The number of spaces to indent the printing (each level
/// increases by 3)
///
void printFormatted(int aIndent = 0) const;
/// Print the node in the format of %Newick tree.
///
void printNode(void) const;
/// Print the node in the format of %Newick tree (without branch length).
///
void printNodeWoutLen(void) const;
/// Clear the node.
///
void clearNode(void);
/// Get the node label.
///
/// @return The node label
///
const std::string &getLabel(void) const { return mNodeName; }
/// Get the node type from file.
///
/// @return The node marker
///
const std::string &getType(void) const { return mNodeMark; }
/// Check if the node is a leaf.
///
/// @return True if the node has no descendants
///
bool isLeaf(void) const { return mChildrenList.empty(); }
/// Return one of the node children.
///
/// @param[in] aIdx Index of the child to be returned
///
/// @return Pointer to the child node or NULL if the index is out of range
///
TreeNode *getChild(unsigned int aIdx) const {
if (aIdx >= static_cast<unsigned int>(mChildrenList.size()))
return NULL;
return mChildrenList[aIdx];
}
/// Get the branch length.
///
/// @return The branch length
///
double getLen(void) const { return mBranchLength; }
/// Get the pointer to the parent
///
/// @return The pointer to the parent
///
TreeNode *getParent() const { return mParent; }
/// Delete a child from the node (only used in unrooting tree).
///
/// @param[in] aNode The child node
///
bool delChild(unsigned int aIdx) {
if (aIdx >= static_cast<unsigned int>(mChildrenList.size()))
return false;
if (aIdx == 1)
mChildrenList.pop_back();
else {
TreeNode *t = mChildrenList[1];
mChildrenList.pop_back();
mChildrenList.pop_back();
mChildrenList.push_back(t);
}
return true;
}
private:
TreeNode *mParent; ///< Pointer to the node parent (null for the root)
double mBranchLength; ///< Length of the branch leading to this node as read
/// from the file (not valid for the root)
std::vector<TreeNode *> mChildrenList; ///< List of the node children
std::string mNodeName; ///< Node label
std::string mNodeMark; ///< Node type or empty if the '#' part is not present
};
#endif