--- /dev/null
+#include "muscle.h"\r
+#include "msa.h"\r
+#include "pwpath.h"\r
+#include "profile.h"\r
+\r
+#define TRACE 0\r
+\r
+static void AppendDelete(const MSA &msaA, unsigned &uColIndexA,\r
+ unsigned uSeqCountA, unsigned uSeqCountB, MSA &msaCombined,\r
+ unsigned &uColIndexCombined)\r
+ {\r
+#if TRACE\r
+ Log("AppendDelete ColIxA=%u ColIxCmb=%u\n",\r
+ uColIndexA, uColIndexCombined);\r
+#endif\r
+ for (unsigned uSeqIndexA = 0; uSeqIndexA < uSeqCountA; ++uSeqIndexA)\r
+ {\r
+ char c = msaA.GetChar(uSeqIndexA, uColIndexA);\r
+ msaCombined.SetChar(uSeqIndexA, uColIndexCombined, c);\r
+ }\r
+\r
+ for (unsigned uSeqIndexB = 0; uSeqIndexB < uSeqCountB; ++uSeqIndexB)\r
+ msaCombined.SetChar(uSeqCountA + uSeqIndexB, uColIndexCombined, '-');\r
+\r
+ ++uColIndexCombined;\r
+ ++uColIndexA;\r
+ }\r
+\r
+static void AppendInsert(const MSA &msaB, unsigned &uColIndexB,\r
+ unsigned uSeqCountA, unsigned uSeqCountB, MSA &msaCombined,\r
+ unsigned &uColIndexCombined)\r
+ {\r
+#if TRACE\r
+ Log("AppendInsert ColIxB=%u ColIxCmb=%u\n",\r
+ uColIndexB, uColIndexCombined);\r
+#endif\r
+ for (unsigned uSeqIndexA = 0; uSeqIndexA < uSeqCountA; ++uSeqIndexA)\r
+ msaCombined.SetChar(uSeqIndexA, uColIndexCombined, '-');\r
+\r
+ for (unsigned uSeqIndexB = 0; uSeqIndexB < uSeqCountB; ++uSeqIndexB)\r
+ {\r
+ char c = msaB.GetChar(uSeqIndexB, uColIndexB);\r
+ msaCombined.SetChar(uSeqCountA + uSeqIndexB, uColIndexCombined, c);\r
+ }\r
+\r
+ ++uColIndexCombined;\r
+ ++uColIndexB;\r
+ }\r
+\r
+static void AppendUnalignedTerminals(const MSA &msaA, unsigned &uColIndexA, unsigned uColCountA,\r
+ const MSA &msaB, unsigned &uColIndexB, unsigned uColCountB, unsigned uSeqCountA,\r
+ unsigned uSeqCountB, MSA &msaCombined, unsigned &uColIndexCombined)\r
+ {\r
+#if TRACE\r
+ Log("AppendUnalignedTerminals ColIxA=%u ColIxB=%u ColIxCmb=%u\n",\r
+ uColIndexA, uColIndexB, uColIndexCombined);\r
+#endif\r
+ const unsigned uLengthA = msaA.GetColCount();\r
+ const unsigned uLengthB = msaB.GetColCount();\r
+\r
+ unsigned uNewColCount = uColCountA;\r
+ if (uColCountB > uNewColCount)\r
+ uNewColCount = uColCountB;\r
+\r
+ for (unsigned n = 0; n < uColCountA; ++n)\r
+ {\r
+ for (unsigned uSeqIndexA = 0; uSeqIndexA < uSeqCountA; ++uSeqIndexA)\r
+ {\r
+ char c = msaA.GetChar(uSeqIndexA, uColIndexA + n);\r
+ c = UnalignChar(c);\r
+ msaCombined.SetChar(uSeqIndexA, uColIndexCombined + n, c);\r
+ }\r
+ }\r
+ for (unsigned n = uColCountA; n < uNewColCount; ++n)\r
+ {\r
+ for (unsigned uSeqIndexA = 0; uSeqIndexA < uSeqCountA; ++uSeqIndexA)\r
+ msaCombined.SetChar(uSeqIndexA, uColIndexCombined + n, '.');\r
+ }\r
+\r
+ for (unsigned n = 0; n < uColCountB; ++n)\r
+ {\r
+ for (unsigned uSeqIndexB = 0; uSeqIndexB < uSeqCountB; ++uSeqIndexB)\r
+ {\r
+ char c = msaB.GetChar(uSeqIndexB, uColIndexB + n);\r
+ c = UnalignChar(c);\r
+ msaCombined.SetChar(uSeqCountA + uSeqIndexB, uColIndexCombined + n, c);\r
+ }\r
+ }\r
+ for (unsigned n = uColCountB; n < uNewColCount; ++n)\r
+ {\r
+ for (unsigned uSeqIndexB = 0; uSeqIndexB < uSeqCountB; ++uSeqIndexB)\r
+ msaCombined.SetChar(uSeqCountA + uSeqIndexB, uColIndexCombined + n, '.');\r
+ }\r
+\r
+ uColIndexCombined += uNewColCount;\r
+ uColIndexA += uColCountA;\r
+ uColIndexB += uColCountB;\r
+ }\r
+\r
+static void AppendMatch(const MSA &msaA, unsigned &uColIndexA, const MSA &msaB,\r
+ unsigned &uColIndexB, unsigned uSeqCountA, unsigned uSeqCountB,\r
+ MSA &msaCombined, unsigned &uColIndexCombined)\r
+ {\r
+#if TRACE\r
+ Log("AppendMatch ColIxA=%u ColIxB=%u ColIxCmb=%u\n",\r
+ uColIndexA, uColIndexB, uColIndexCombined);\r
+#endif\r
+\r
+ for (unsigned uSeqIndexA = 0; uSeqIndexA < uSeqCountA; ++uSeqIndexA)\r
+ {\r
+ char c = msaA.GetChar(uSeqIndexA, uColIndexA);\r
+ msaCombined.SetChar(uSeqIndexA, uColIndexCombined, c);\r
+ }\r
+\r
+ for (unsigned uSeqIndexB = 0; uSeqIndexB < uSeqCountB; ++uSeqIndexB)\r
+ {\r
+ char c = msaB.GetChar(uSeqIndexB, uColIndexB);\r
+ msaCombined.SetChar(uSeqCountA + uSeqIndexB, uColIndexCombined, c);\r
+ }\r
+\r
+ ++uColIndexA;\r
+ ++uColIndexB;\r
+ ++uColIndexCombined;\r
+ }\r
+\r
+void AlignTwoMSAsGivenPathSW(const PWPath &Path, const MSA &msaA, const MSA &msaB,\r
+ MSA &msaCombined)\r
+ {\r
+ msaCombined.Clear();\r
+\r
+#if TRACE\r
+ Log("AlignTwoMSAsGivenPathSW\n");\r
+ Log("Template A:\n");\r
+ msaA.LogMe();\r
+ Log("Template B:\n");\r
+ msaB.LogMe();\r
+#endif\r
+\r
+ const unsigned uColCountA = msaA.GetColCount();\r
+ const unsigned uColCountB = msaB.GetColCount();\r
+\r
+ const unsigned uSeqCountA = msaA.GetSeqCount();\r
+ const unsigned uSeqCountB = msaB.GetSeqCount();\r
+\r
+ msaCombined.SetSeqCount(uSeqCountA + uSeqCountB);\r
+\r
+// Copy sequence names into combined MSA\r
+ for (unsigned uSeqIndexA = 0; uSeqIndexA < uSeqCountA; ++uSeqIndexA)\r
+ {\r
+ msaCombined.SetSeqName(uSeqIndexA, msaA.GetSeqName(uSeqIndexA));\r
+ msaCombined.SetSeqId(uSeqIndexA, msaA.GetSeqId(uSeqIndexA));\r
+ }\r
+\r
+ for (unsigned uSeqIndexB = 0; uSeqIndexB < uSeqCountB; ++uSeqIndexB)\r
+ {\r
+ msaCombined.SetSeqName(uSeqCountA + uSeqIndexB, msaB.GetSeqName(uSeqIndexB));\r
+ msaCombined.SetSeqId(uSeqCountA + uSeqIndexB, msaB.GetSeqId(uSeqIndexB));\r
+ }\r
+\r
+ unsigned uColIndexA = 0;\r
+ unsigned uColIndexB = 0;\r
+ unsigned uColIndexCombined = 0;\r
+ const unsigned uEdgeCount = Path.GetEdgeCount();\r
+ for (unsigned uEdgeIndex = 0; uEdgeIndex < uEdgeCount; ++uEdgeIndex)\r
+ {\r
+ const PWEdge &Edge = Path.GetEdge(uEdgeIndex);\r
+#if TRACE\r
+ Log("\nEdge %u %c%u.%u\n",\r
+ uEdgeIndex,\r
+ Edge.cType,\r
+ Edge.uPrefixLengthA,\r
+ Edge.uPrefixLengthB);\r
+#endif\r
+ const char cType = Edge.cType;\r
+ const unsigned uPrefixLengthA = Edge.uPrefixLengthA;\r
+ unsigned uColCountA = 0;\r
+ if (uPrefixLengthA > 0)\r
+ {\r
+ const unsigned uNodeIndexA = uPrefixLengthA - 1;\r
+ const unsigned uTplColIndexA = uNodeIndexA;\r
+ if (uTplColIndexA > uColIndexA)\r
+ uColCountA = uTplColIndexA - uColIndexA;\r
+ }\r
+\r
+ const unsigned uPrefixLengthB = Edge.uPrefixLengthB;\r
+ unsigned uColCountB = 0;\r
+ if (uPrefixLengthB > 0)\r
+ {\r
+ const unsigned uNodeIndexB = uPrefixLengthB - 1;\r
+ const unsigned uTplColIndexB = uNodeIndexB;\r
+ if (uTplColIndexB > uColIndexB)\r
+ uColCountB = uTplColIndexB - uColIndexB;\r
+ }\r
+\r
+ AppendUnalignedTerminals(msaA, uColIndexA, uColCountA, msaB, uColIndexB, uColCountB,\r
+ uSeqCountA, uSeqCountB, msaCombined, uColIndexCombined);\r
+\r
+ switch (cType)\r
+ {\r
+ case 'M':\r
+ {\r
+ assert(uPrefixLengthA > 0);\r
+ assert(uPrefixLengthB > 0);\r
+ const unsigned uColA = uPrefixLengthA - 1;\r
+ const unsigned uColB = uPrefixLengthB - 1;\r
+ assert(uColIndexA == uColA);\r
+ assert(uColIndexB == uColB);\r
+ AppendMatch(msaA, uColIndexA, msaB, uColIndexB, uSeqCountA, uSeqCountB,\r
+ msaCombined, uColIndexCombined);\r
+ break;\r
+ }\r
+ case 'D':\r
+ {\r
+ assert(uPrefixLengthA > 0);\r
+ const unsigned uColA = uPrefixLengthA - 1;\r
+ assert(uColIndexA == uColA);\r
+ AppendDelete(msaA, uColIndexA, uSeqCountA, uSeqCountB, msaCombined, uColIndexCombined);\r
+ break;\r
+ }\r
+ case 'I':\r
+ {\r
+ assert(uPrefixLengthB > 0);\r
+ const unsigned uColB = uPrefixLengthB - 1;\r
+ assert(uColIndexB == uColB);\r
+ AppendInsert(msaB, uColIndexB, uSeqCountA, uSeqCountB, msaCombined, uColIndexCombined);\r
+ break;\r
+ }\r
+ default:\r
+ assert(false);\r
+ }\r
+ }\r
+ unsigned uInsertColCountA = uColCountA - uColIndexA;\r
+ unsigned uInsertColCountB = uColCountB - uColIndexB;\r
+\r
+ AppendUnalignedTerminals(msaA, uColIndexA, uInsertColCountA, msaB, uColIndexB,\r
+ uInsertColCountB, uSeqCountA, uSeqCountB, msaCombined, uColIndexCombined);\r
+ }\r