File: realigndiffs.cpp

package info (click to toggle)
muscle 3.60-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,384 kB
  • ctags: 2,079
  • sloc: cpp: 26,452; xml: 185; makefile: 101
file content (115 lines) | stat: -rw-r--r-- 2,846 bytes parent folder | download | duplicates (14)
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
#include "muscle.h"
#include "msa.h"
#include "tree.h"
#include "profile.h"
#include "pwpath.h"

#define TRACE	0

// Progressive alignment according to a diffs tree.

static void MakeNode(const MSA &msaIn, const Tree &Diffs, unsigned uDiffsNodeIndex,
   const unsigned IdToDiffsTreeNodeIndex[], ProgNode &Node)
	{
	const unsigned uSeqCount = msaIn.GetSeqCount();

	unsigned *Ids = new unsigned[uSeqCount];

	unsigned uSeqsInDiffCount = 0;
	for (unsigned uId = 0; uId < uSeqCount; ++uId)
		{
		if (IdToDiffsTreeNodeIndex[uId] == uDiffsNodeIndex)
			{
			Ids[uSeqsInDiffCount] = uId;
			++uSeqsInDiffCount;
			}
		}
	if (0 == uSeqsInDiffCount)
		Quit("MakeNode: no seqs in diff");

	MSASubsetByIds(msaIn, Ids, uSeqsInDiffCount, Node.m_MSA);

#if	DEBUG
	ValidateMuscleIds(Node.m_MSA);
#endif

	DeleteGappedCols(Node.m_MSA);
	delete[] Ids;
	}

void RealignDiffs(const MSA &msaIn, const Tree &Diffs,
  const unsigned IdToDiffsTreeNodeIndex[], MSA &msaOut)
	{
	assert(Diffs.IsRooted());

#if	TRACE
	Log("RealignDiffs\n");
	Log("Diff tree:\n");
	Diffs.LogMe();
#endif

	const unsigned uNodeCount = Diffs.GetNodeCount();
	if (uNodeCount%2 == 0)
		Quit("RealignDiffs: Expected odd number of nodes");

	const unsigned uMergeCount = (uNodeCount - 1)/2;

	ProgNode *ProgNodes = new ProgNode[uNodeCount];

	unsigned uJoin = 0;
	SetProgressDesc("Refine tree");
	for (unsigned uDiffsNodeIndex = Diffs.FirstDepthFirstNode();
	  NULL_NEIGHBOR != uDiffsNodeIndex;
	  uDiffsNodeIndex = Diffs.NextDepthFirstNode(uDiffsNodeIndex))
		{
		if (Diffs.IsLeaf(uDiffsNodeIndex))
			{
			assert(uDiffsNodeIndex < uNodeCount);
			if (uDiffsNodeIndex >= uNodeCount)
				Quit("TreeNodeIndex=%u NodeCount=%u\n", uDiffsNodeIndex, uNodeCount);

			ProgNode &Node = ProgNodes[uDiffsNodeIndex];
			MakeNode(msaIn, Diffs, uDiffsNodeIndex, IdToDiffsTreeNodeIndex, Node);

			Node.m_uLength = Node.m_MSA.GetColCount();
			}
		else
			{
			Progress(uJoin, uMergeCount);
			++uJoin;
			const unsigned uMergeNodeIndex = uDiffsNodeIndex;
			ProgNode &Parent = ProgNodes[uMergeNodeIndex];

			const unsigned uLeft = Diffs.GetLeft(uDiffsNodeIndex);
			const unsigned uRight = Diffs.GetRight(uDiffsNodeIndex);

			ProgNode &Node1 = ProgNodes[uLeft];
			ProgNode &Node2 = ProgNodes[uRight];

			PWPath Path;
			AlignTwoMSAs(Node1.m_MSA, Node2.m_MSA, Parent.m_MSA, Path);

#if	TRACE
			{
			Log("Combined:\n");
			Parent.m_MSA.LogMe();
			}
#endif

			Node1.m_MSA.Clear();
			Node2.m_MSA.Clear();
			}
		}
	ProgressStepsDone();

	unsigned uRootNodeIndex = Diffs.GetRootNodeIndex();
	const ProgNode &RootProgNode = ProgNodes[uRootNodeIndex];
	msaOut.Copy(RootProgNode.m_MSA);

#if	DEBUG
	AssertMSAEqIgnoreCaseAndGaps(msaIn, msaOut);
#endif

	delete[] ProgNodes;
	ProgNodes = 0;
	}