src/lib/seqOut.c 1.28
1.28 2009/08/21 18:39:59 angie
Added bafFlushLineNoHr for more compact side-by-side alignment display.
Index: src/lib/seqOut.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/lib/seqOut.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -b -B -U 1000000 -r1.27 -r1.28
--- src/lib/seqOut.c 26 Mar 2007 18:11:48 -0000 1.27
+++ src/lib/seqOut.c 21 Aug 2009 18:39:59 -0000 1.28
@@ -1,325 +1,331 @@
/* seqOut - stuff to output sequences and alignments in web
* or ascii viewable form.
*
* This file is copyright 2002 Jim Kent, but license is hereby
* granted for all use - public, private or commercial. */
#include "common.h"
#include "obscure.h"
#include "dnautil.h"
#include "fuzzyFind.h"
#include "seqOut.h"
#include "htmshell.h"
#include "axt.h"
static char const rcsid[] = "$Id$";
struct cfm *cfmNew(int wordLen, int lineLen,
boolean lineNumbers, boolean countDown, FILE *out, int numOff)
/* Set up colored sequence formatting for html. */
{
struct cfm *cfm;
AllocVar(cfm);
cfm->inWord = cfm->inLine = cfm->charCount = 0;
cfm->color = 0;
cfm->wordLen = wordLen;
cfm->lineLen = lineLen;
cfm->lineNumbers = lineNumbers;
cfm->countDown = countDown;
cfm->out = out;
cfm->numOff = numOff;
cfm->bold = cfm->underline = cfm->italic = FALSE;
return cfm;
}
static void cfmPopFormat(struct cfm *cfm)
/* Restore format to default. */
{
if (cfm->color != 0)
fprintf(cfm->out, "</FONT>");
if (cfm->underline)
fprintf(cfm->out, "</U>");
if (cfm->bold)
fprintf(cfm->out, "</B>");
if (cfm->italic)
fprintf(cfm->out, "</I>");
}
static void cfmPushFormat(struct cfm *cfm)
/* Set format. */
{
if (cfm->italic)
fprintf(cfm->out, "<I>");
if (cfm->bold)
fprintf(cfm->out, "<B>");
if (cfm->underline)
fprintf(cfm->out, "<U>");
if (cfm->color != 0)
fprintf(cfm->out, "<FONT COLOR=\"#%06X\">", cfm->color);
}
void cfmOutExt(struct cfm *cfm, char c, int color, boolean underline, boolean bold, boolean italic)
/* Write out a byte, and formatting extras */
{
if (color != cfm->color || underline != cfm->underline
|| bold != cfm->bold || italic != cfm->italic)
{
cfmPopFormat(cfm);
cfm->color = color;
cfm->underline = underline;
cfm->bold = bold;
cfm->italic = italic;
cfmPushFormat(cfm);
}
++cfm->charCount;
fputc(c, cfm->out);
if (cfm->wordLen)
{
if (++cfm->inWord >= cfm->wordLen)
{
cfmPopFormat(cfm);
fputc(' ', cfm->out);
cfmPushFormat(cfm);
cfm->inWord = 0;
}
}
if (cfm->lineLen)
{
if (++cfm->inLine >= cfm->lineLen)
{
if (cfm->lineNumbers)
{
int pos = cfm->charCount;
if (cfm->countDown)
{
pos = 1-pos;
}
pos += cfm->numOff;
cfmPopFormat(cfm);
fprintf(cfm->out, " %d", pos);
cfmPushFormat(cfm);
}
fprintf(cfm->out, "\n");
cfm->inLine = 0;
}
}
}
void cfmOut(struct cfm *cfm, char c, int color)
/* Write out a byte, and depending on color formatting extras */
{
cfmOutExt(cfm, c, color, FALSE, FALSE, FALSE);
}
void cfmFree(struct cfm **pCfm)
/* Finish up cfm formatting job. */
{
struct cfm *cfm = *pCfm;
if (cfm != NULL)
{
cfmPopFormat(cfm);
freez(pCfm);
}
}
int seqOutColorLookup[] =
{
0x000000,
0x3300FF,
0x22CCEE,
0xFF0033,
0xFFcc22,
0x00aa00,
0xFF0000,
};
void bafInit(struct baf *baf, DNA *needle, int nNumOff, boolean nCountDown,
DNA *haystack, int hNumOff, boolean hCountDown, FILE *out,
int lineSize, boolean isTrans )
/* Initialize block alignment formatter. */
{
baf->cix = 0;
baf->needle = needle;
baf->nCountDown = nCountDown;
baf->haystack = haystack;
baf->nNumOff = nNumOff;
baf->hNumOff = hNumOff;
baf->hCountDown = hCountDown;
baf->out = out;
baf->lineSize = lineSize;
baf->isTrans = isTrans;
baf->nCurPos = baf->hCurPos = 0;
baf->nLineStart = baf->hLineStart = 0;
}
void bafSetAli(struct baf *baf, struct ffAli *ali)
/* Set up block formatter around an ffAli block. */
{
baf->nCurPos = ali->nStart - baf->needle;
baf->hCurPos = ali->hStart - baf->haystack;
}
void bafSetPos(struct baf *baf, int nStart, int hStart)
/* Set up block formatter starting at nStart/hStart. */
{
if (baf->isTrans)
nStart *= 3;
baf->nCurPos = nStart;
baf->hCurPos = hStart;
}
void bafStartLine(struct baf *baf)
/* Set up block formatter to start new line at current position. */
{
baf->nLineStart = baf->nCurPos;
baf->hLineStart = baf->hCurPos;
}
static int maxDigits(int x, int y)
{
int xDigits = digitsBaseTen(x);
int yDigits = digitsBaseTen(y);
return (xDigits > yDigits ? xDigits : yDigits);
}
void bafWriteLine(struct baf *baf)
/* Write out a line of an alignment (which takes up
* three lines on the screen. */
{
int i;
int count = baf->cix;
int nStart = baf->nLineStart + 1 + baf->nNumOff;
int hStart = baf->hLineStart + 1 + baf->hNumOff;
int nEnd = baf->nCurPos + baf->nNumOff;
int hEnd = baf->hCurPos + baf->hNumOff;
int startDigits = maxDigits(nStart, hStart);
int endDigits = maxDigits(nEnd, hEnd);
int hStartNum, hEndNum;
int nStartNum, nEndNum;
static struct axtScoreScheme *ss = 0; /* Scoring scheme. */
struct cfm cfm;
extern char blosumText[];
extern struct axtScoreScheme *axtScoreSchemeFromProteinText(char *text, char *fileName);
boolean revArrows = (baf->nCountDown ^ baf->hCountDown);
char arrowChar = (revArrows ? '<' : '>');
ZeroVar(&cfm);
cfm.out = baf->out;
if (ss == 0)
ss = axtScoreSchemeFromProteinText(blosumText, "fake");
if (baf->nCountDown)
{
nStartNum = baf->nNumOff - baf->nLineStart;
nEndNum = 1+baf->nNumOff - baf->nCurPos;
}
else
{
nStartNum = 1+baf->nNumOff + baf->nLineStart;
nEndNum = baf->nNumOff + baf->nCurPos;
}
fprintf(baf->out, "%0*d ", startDigits, nStartNum);
for (i=0; i<count; ++i)
fputc(baf->nChars[i], baf->out);
fprintf(baf->out, " %0*d\n", endDigits, nEndNum);
for (i=0; i<startDigits; ++i)
fputc(arrowChar, baf->out);
fputc(' ', baf->out);
for (i=0; i<count; ++i)
{
char n,h,c = ' ';
n = baf->nChars[i];
h = baf->hChars[i];
if (baf->isTrans)
{
if (n != ' ')
{
DNA codon[4];
codon[0] = baf->hChars[i-1];
codon[1] = h;
codon[2] = baf->hChars[i+1];
codon[3] = 0;
tolowers(codon);
c = lookupCodon(codon);
cfmPushFormat(&cfm);
if (toupper(n) == c)
cfmOut(&cfm, '|', seqOutColorLookup[0]);
else
{
int color;
if (c == 0)
c = 'X';
if (ss->matrix[(int)toupper(n)][(int)c] > 0)
color = 5;
else
color = 6;
cfmOut(&cfm, c, seqOutColorLookup[color]);
}
cfmPopFormat(&cfm);
}
else
{
fputc(c, baf->out);
}
}
else
{
if (toupper(n) == toupper(h))
c = '|';
fputc(c, baf->out);
}
}
fputc(' ', baf->out);
for (i=0; i<endDigits; ++i)
fputc(arrowChar, baf->out);
fprintf(baf->out, "\n");
if (baf->hCountDown)
{
hStartNum = baf->hNumOff - baf->hLineStart;
hEndNum = 1+baf->hNumOff - baf->hCurPos;
}
else
{
hStartNum = 1+baf->hNumOff + baf->hLineStart;
hEndNum = baf->hNumOff + baf->hCurPos;
}
fprintf(baf->out, "%0*d ", startDigits, hStartNum);
for (i=0; i<count; ++i)
fputc(baf->hChars[i], baf->out);
fprintf(baf->out, " %0*d\n\n", endDigits, hEndNum);
}
void bafOut(struct baf *baf, char n, char h)
/* Write a pair of character to block alignment. */
{
baf->nChars[baf->cix] = n;
baf->hChars[baf->cix] = h;
if (n != '.' && n != '-')
baf->nCurPos += 1;
if (h != '.' && h != '-')
baf->hCurPos += 1;
if (++(baf->cix) >= baf->lineSize)
{
bafWriteLine(baf);
baf->cix = 0;
baf->nLineStart = baf->nCurPos;
baf->hLineStart = baf->hCurPos;
}
}
-void bafFlushLine(struct baf *baf)
-/* Write out alignment line if it has any characters in it. */
+void bafFlushLineNoHr(struct baf *baf)
+/* Write out alignment line if it has any characters in it (no <HR>). */
{
if (baf->cix > 0)
bafWriteLine(baf);
fflush(baf->out);
-fprintf(baf->out, "<HR ALIGN=\"CENTER\">");
baf->cix = 0;
}
+void bafFlushLine(struct baf *baf)
+/* Write out alignment line if it has any characters in it, and an <HR>. */
+{
+bafFlushLineNoHr(baf);
+fprintf(baf->out, "<HR ALIGN=\"CENTER\">");
+}
+