📄 tree.h
字号:
#ifndef tree_h
#define tree_h
#include <limits.h>
class Clust;
const unsigned NULL_NEIGHBOR = UINT_MAX;
enum NEWICK_TOKEN_TYPE
{
NTT_Unknown,
// Returned from Tree::GetToken:
NTT_Lparen,
NTT_Rparen,
NTT_Colon,
NTT_Comma,
NTT_Semicolon,
NTT_String,
// Following are never returned from Tree::GetToken:
NTT_SingleQuotedString,
NTT_DoubleQuotedString,
NTT_Comment
};
class Tree
{
public:
Tree()
{
m_uNodeCount = 0;
m_uCacheCount = 0;
m_uNeighbor1 = 0;
m_uNeighbor2 = 0;
m_uNeighbor3 = 0;
m_dEdgeLength1 = 0;
m_dEdgeLength2 = 0;
m_dEdgeLength3 = 0;
m_dHeight = 0;
m_bHasEdgeLength1 = 0;
m_bHasEdgeLength2 = 0;
m_bHasEdgeLength3 = 0;
m_bHasHeight = 0;
m_ptrName = 0;
m_Ids = 0;
}
virtual ~Tree()
{
Clear();
}
void Clear()
{
for (unsigned n = 0; n < m_uNodeCount; ++n)
free(m_ptrName[n]);
m_uNodeCount = 0;
m_uCacheCount = 0;
delete[] m_uNeighbor1;
delete[] m_uNeighbor2;
delete[] m_uNeighbor3;
delete[] m_dEdgeLength1;
delete[] m_dEdgeLength2;
delete[] m_dEdgeLength3;
delete[] m_bHasEdgeLength1;
delete[] m_bHasEdgeLength2;
delete[] m_bHasEdgeLength3;
delete[] m_ptrName;
delete[] m_Ids;
delete[] m_bHasHeight;
delete[] m_dHeight;
m_uNeighbor1 = 0;
m_uNeighbor2 = 0;
m_uNeighbor3 = 0;
m_dEdgeLength1 = 0;
m_dEdgeLength2 = 0;
m_dEdgeLength3 = 0;
m_ptrName = 0;
m_Ids = 0;
m_uRootNodeIndex = 0;
m_bHasHeight = 0;
m_dHeight = 0;
m_bRooted = false;
}
// Creation and manipulation
void CreateRooted();
void CreateUnrooted(double dEdgeLength);
void FromFile(TextFile &File);
void FromClust(Clust &C);
void Copy(const Tree &tree);
void Create(unsigned uLeafCount, unsigned uRoot, const unsigned Left[],
const unsigned Right[], const float LeftLength[], const float RightLength[],
const unsigned LeafIds[], char *LeafNames[]);
unsigned AppendBranch(unsigned uExistingNodeIndex);
void SetLeafName(unsigned uNodeIndex, const char *ptrName);
void SetLeafId(unsigned uNodeIndex, unsigned uId);
void SetEdgeLength(unsigned uNodeIndex1, unsigned uNodeIndex2,
double dLength);
void RootUnrootedTree(unsigned uNodeIndex1, unsigned uNodeIndex2);
void RootUnrootedTree(ROOT Method);
void UnrootByDeletingRoot();
// Saving to file
void ToFile(TextFile &File) const;
// Accessor functions
unsigned GetNodeCount() const
{
return m_uNodeCount;
}
unsigned GetLeafCount() const
{
if (m_bRooted)
{
assert(m_uNodeCount%2 == 1);
return (m_uNodeCount + 1)/2;
}
else
{
assert(m_uNodeCount%2 == 0);
return (m_uNodeCount + 2)/2;
}
}
unsigned GetNeighbor(unsigned uNodeIndex, unsigned uNeighborSubscript) const;
unsigned GetNeighbor1(unsigned uNodeIndex) const
{
assert(uNodeIndex < m_uNodeCount);
return m_uNeighbor1[uNodeIndex];
}
unsigned GetNeighbor2(unsigned uNodeIndex) const
{
assert(uNodeIndex < m_uNodeCount);
return m_uNeighbor2[uNodeIndex];
}
unsigned GetNeighbor3(unsigned uNodeIndex) const
{
assert(uNodeIndex < m_uNodeCount);
return m_uNeighbor3[uNodeIndex];
}
unsigned GetParent(unsigned uNodeIndex) const
{
assert(m_bRooted && uNodeIndex < m_uNodeCount);
return m_uNeighbor1[uNodeIndex];
}
bool IsRooted() const
{
return m_bRooted;
}
unsigned GetLeft(unsigned uNodeIndex) const
{
assert(m_bRooted && uNodeIndex < m_uNodeCount);
return m_uNeighbor2[uNodeIndex];
}
unsigned GetRight(unsigned uNodeIndex) const
{
assert(m_bRooted && uNodeIndex < m_uNodeCount);
return m_uNeighbor3[uNodeIndex];
}
const char *GetName(unsigned uNodeIndex) const
{
assert(uNodeIndex < m_uNodeCount);
return m_ptrName[uNodeIndex];
}
unsigned GetRootNodeIndex() const
{
assert(m_bRooted);
return m_uRootNodeIndex;
}
unsigned GetNeighborCount(unsigned uNodeIndex) const
{
const unsigned n1 = m_uNeighbor1[uNodeIndex];
const unsigned n2 = m_uNeighbor2[uNodeIndex];
const unsigned n3 = m_uNeighbor3[uNodeIndex];
return (NULL_NEIGHBOR != n1) + (NULL_NEIGHBOR != n2) + (NULL_NEIGHBOR != n3);
}
bool IsLeaf(unsigned uNodeIndex) const
{
assert(uNodeIndex < m_uNodeCount);
if (1 == m_uNodeCount)
return true;
return 1 == GetNeighborCount(uNodeIndex);
}
bool IsRoot(unsigned uNodeIndex) const
{
return IsRooted() && m_uRootNodeIndex == uNodeIndex;
}
unsigned GetLeafId(unsigned uNodeIndex) const;
unsigned GetLeafNodeIndex(const char *ptrName) const;
bool IsEdge(unsigned uNodeIndex1, unsigned uNodeIndex2) const;
bool HasEdgeLength(unsigned uNodeIndex1, unsigned uNodeIndex2) const;
double GetEdgeLength(unsigned uNodeIndex1, unsigned uNodeIndex2) const;
const char *GetLeafName(unsigned uNodeIndex) const;
unsigned GetNeighborSubscript(unsigned uNodeIndex, unsigned uNeighborIndex) const;
double GetNodeHeight(unsigned uNodeIndex) const;
// Depth-first traversal
unsigned FirstDepthFirstNode() const;
unsigned NextDepthFirstNode(unsigned uNodeIndex) const;
unsigned FirstDepthFirstNodeR() const;
unsigned NextDepthFirstNodeR(unsigned uNodeIndex) const;
// Equivalent of GetLeft/Right in unrooted tree, works in rooted tree too.
unsigned GetFirstNeighbor(unsigned uNodeIndex, unsigned uNeighborIndex) const;
unsigned GetSecondNeighbor(unsigned uNodeIndex, unsigned uNeighborIndex) const;
// Getting parent node in unrooted tree defined iff leaf
unsigned GetLeafParent(unsigned uNodeIndex) const;
// Misc
const char *NTTStr(NEWICK_TOKEN_TYPE NTT) const;
void FindCenterByLongestSpan(unsigned *ptrNodeIndex1,
unsigned *ptrNodeIndex2) const;
void PruneTree(const Tree &tree, unsigned Subfams[],
unsigned uSubfamCount);
unsigned LeafIndexToNodeIndex(unsigned uLeafIndex) const;
// Debugging & trouble-shooting support
void Validate() const;
void ValidateNode(unsigned uNodeIndex) const;
void AssertAreNeighbors(unsigned uNodeIndex1, unsigned uNodeIndex2) const;
void LogMe() const;
private:
unsigned UnrootFromFile();
NEWICK_TOKEN_TYPE GetTokenVerbose(TextFile &File, char szToken[],
unsigned uBytes) const
{
NEWICK_TOKEN_TYPE NTT = GetToken(File, szToken, uBytes);
Log("GetToken %10.10s %s\n", NTTStr(NTT), szToken);
return NTT;
}
void InitCache(unsigned uCacheCount);
void ExpandCache();
NEWICK_TOKEN_TYPE GetToken(TextFile &File, char szToken[], unsigned uBytes) const;
bool GetGroupFromFile(TextFile &File, unsigned uNodeIndex, double *ptrdEdgeLength);
unsigned GetLeafCountUnrooted(unsigned uNodeIndex1, unsigned uNodeIndex2,
double *ptrdTotalDistance) const;
void ToFileNodeRooted(TextFile &File, unsigned uNodeIndex) const;
void ToFileNodeUnrooted(TextFile &File, unsigned uNodeIndex, unsigned uParent) const;
void OrientParent(unsigned uNodeIndex, unsigned uParentNodeIndex);
double FromClustNode(const Clust &C, unsigned uClustNodeIndex, unsigned uPhyNodeIndex);
unsigned GetAnyNonLeafNode() const;
// Yuck. Data is made public for the convenience of Tree::Copy.
// There has to be a better way.
public:
unsigned m_uNodeCount;
unsigned m_uCacheCount;
unsigned *m_uNeighbor1;
unsigned *m_uNeighbor2;
unsigned *m_uNeighbor3;
double *m_dEdgeLength1;
double *m_dEdgeLength2;
double *m_dEdgeLength3;
double *m_dHeight;
bool *m_bHasEdgeLength1;
bool *m_bHasEdgeLength2;
bool *m_bHasEdgeLength3;
bool *m_bHasHeight;
unsigned *m_Ids;
char **m_ptrName;
bool m_bRooted;
unsigned m_uRootNodeIndex;
};
struct PhyEnumEdgeState
{
PhyEnumEdgeState()
{
m_bInit = false;
m_uNodeIndex1 = NULL_NEIGHBOR;
m_uNodeIndex2 = NULL_NEIGHBOR;
}
bool m_bInit;
unsigned m_uNodeIndex1;
unsigned m_uNodeIndex2;
};
const unsigned NODE_CHANGED = (unsigned) (~0);
extern bool PhyEnumBiParts(const Tree &tree, PhyEnumEdgeState &ES,
unsigned Leaves1[], unsigned *ptruCount1,
unsigned Leaves2[], unsigned *ptruCount2);
extern bool PhyEnumBiPartsR(const Tree &tree, PhyEnumEdgeState &ES,
unsigned Leaves1[], unsigned *ptruCount1,
unsigned Leaves2[], unsigned *ptruCount2);
extern void ClusterByHeight(const Tree &tree, double dMaxHeight, unsigned Subtrees[],
unsigned *ptruSubtreeCount);
void ClusterBySubfamCount(const Tree &tree, unsigned uSubfamCount,
unsigned Subfams[], unsigned *ptruSubfamCount);
void GetLeaves(const Tree &tree, unsigned uNodeIndex, unsigned Leaves[],
unsigned *ptruLeafCount);
void GetLeavesExcluding(const Tree &tree, unsigned uNodeIndex,
unsigned uExclude, unsigned Leaves[], unsigned *ptruCount);
void GetInternalNodesInHeightOrder(const Tree &tree, unsigned NodeIndexes[]);
void ApplyMinEdgeLength(Tree &tree, double dMinEdgeLength);
void LeafIndexesToLeafNames(const Tree &tree, const unsigned Leaves[], unsigned uCount,
char *Names[]);
void LeafIndexesToIds(const Tree &tree, const unsigned Leaves[], unsigned uCount,
unsigned Ids[]);
void MSASeqSubset(const MSA &msaIn, char *Names[], unsigned uSeqCount,
MSA &msaOut);
void DiffTrees(const Tree &Tree1, const Tree &Tree2, Tree &Diffs,
unsigned IdToDiffsLeafNodeIndex[]);
void DiffTreesE(const Tree &NewTree, const Tree &OldTree,
unsigned NewNodeIndexToOldNodeIndex[]);
void FindRoot(const Tree &tree, unsigned *ptruNode1, unsigned *ptruNode2,
double *ptrdLength1, double *ptrdLength2,
ROOT RootMethod);
void FixRoot(Tree &tree, ROOT RootMethod);
#endif // tree_h
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -