Files
annotate/src/muscle/muscle3.8.31/bittraceback.cpp
alain viari 085a5ff2a7 squared muscle
Former-commit-id: 54638fc7623ec0485109b0b5879144f8f2514213
Former-commit-id: 23f43cd31169d95df12ae1c207d9fd1c924d26b1
2015-11-14 00:11:27 +01:00

207 lines
3.3 KiB
C++

#include "muscle.h"
#include "pwpath.h"
#define TRACE 0
static char XlatEdgeType(char c)
{
if ('E' == c)
return 'D';
if ('J' == c)
return 'I';
return c;
}
static const char *BitsToStr(char Bits)
{
static char Str[] = "xM xD xI";
switch (Bits & BIT_xM)
{
case BIT_MM:
Str[0] = 'M';
break;
case BIT_DM:
Str[0] = 'D';
break;
case BIT_IM:
Str[0] = 'I';
break;
}
switch (Bits & BIT_xD)
{
case BIT_MD:
Str[3] = 'M';
break;
case BIT_DD:
Str[3] = 'D';
break;
}
switch (Bits & BIT_xI)
{
case BIT_MI:
Str[6] = 'M';
break;
case BIT_II:
Str[6] = 'I';
break;
}
return Str;
}
static inline char XChar(char Bits, char cType)
{
switch (cType)
{
case 'M':
{
switch (Bits & BIT_xM)
{
case BIT_MM:
return 'M';
case BIT_DM:
return 'D';
case BIT_IM:
return 'I';
#if DOUBLE_AFFINE
case BIT_EM:
return 'E';
case BIT_JM:
return 'J';
#endif
}
Quit("Huh!?");
return '?';
}
case 'D':
{
switch (Bits & BIT_xD)
{
case BIT_MD:
return 'M';
case BIT_DD:
return 'D';
}
Quit("Huh!?");
return '?';
}
case 'I':
{
switch (Bits & BIT_xI)
{
case BIT_MI:
return 'M';
case BIT_II:
return 'I';
}
Quit("Huh!?");
return '?';
}
#if DOUBLE_AFFINE
case 'E':
{
switch (Bits & BIT_xE)
{
case BIT_ME:
return 'M';
case BIT_EE:
return 'E';
}
Quit("Huh!?");
return '?';
}
case 'J':
{
switch (Bits & BIT_xJ)
{
case BIT_MJ:
return 'M';
case BIT_JJ:
return 'J';
}
Quit("Huh!?");
return '?';
}
#endif
default:
Quit("Huh?");
return '?';
}
}
void BitTraceBack(char **TraceBack, unsigned uLengthA, unsigned uLengthB,
char LastEdge, PWPath &Path)
{
#if TRACE
Log("BitTraceBack\n");
#endif
Path.Clear();
PWEdge Edge;
Edge.uPrefixLengthA = uLengthA;
Edge.uPrefixLengthB = uLengthB;
char Bits = TraceBack[uLengthA][uLengthB];
Edge.cType = LastEdge;
for (;;)
{
#if TRACE
Log("Prepend %c%d.%d\n", Edge.cType, Edge.uPrefixLengthA, Edge.uPrefixLengthB);
#endif
char cSave = Edge.cType;
Edge.cType = XlatEdgeType(cSave);
Path.PrependEdge(Edge);
Edge.cType = cSave;
unsigned PLA = Edge.uPrefixLengthA;
unsigned PLB = Edge.uPrefixLengthB;
char Bits = TraceBack[PLA][PLB];
char NextEdgeType = XChar(Bits, Edge.cType);
#if TRACE
Log("XChar(%s, %c) = %c\n", BitsToStr(Bits), Edge.cType, NextEdgeType);
#endif
switch (Edge.cType)
{
case 'M':
{
if (Edge.uPrefixLengthA == 0)
Quit("BitTraceBack MA=0");
if (Edge.uPrefixLengthB == 0)
Quit("BitTraceBack MA=0");
--(Edge.uPrefixLengthA);
--(Edge.uPrefixLengthB);
break;
}
case 'D':
case 'E':
{
if (Edge.uPrefixLengthA == 0)
Quit("BitTraceBack DA=0");
--(Edge.uPrefixLengthA);
break;
}
case 'I':
case 'J':
{
if (Edge.uPrefixLengthB == 0)
Quit("BitTraceBack IB=0");
--(Edge.uPrefixLengthB);
break;
}
default:
Quit("BitTraceBack: Invalid edge %c", Edge);
}
if (0 == Edge.uPrefixLengthA && 0 == Edge.uPrefixLengthB)
break;
Edge.cType = NextEdgeType;
}
#if TRACE
Path.LogMe();
#endif
}