e70152e44cc66cc599ff6b699eb8adc07f3e656a
kent
Sat May 24 21:09:34 2014 -0700
Adding Copyright NNNN Regents of the University of California to all files I believe with reasonable certainty were developed under UCSC employ or as part of Genome Browser copyright assignment.
diff --git src/hg/hgText/hgWigText.c src/hg/hgText/hgWigText.c
index 145369c..aebb4f6 100644
--- src/hg/hgText/hgWigText.c
+++ src/hg/hgText/hgWigText.c
@@ -1,882 +1,885 @@
/* hgWigText.c - functions for wiggle tracks in hgText */
+/* Copyright (C) 2013 The Regents of the University of California
+ * See README in this or parent directory for licensing information. */
+
#include "common.h"
#include "wiggle.h"
#include "hgColors.h"
#include "web.h"
#include "cheapcgi.h"
#include "hCommon.h"
#include "hgText.h"
#include "hui.h"
#include "customTrack.h"
#include "portable.h"
/* possible two sets of data could be existing */
static struct wiggleData *wigData[2] =
{
(struct wiggleData *)NULL,
(struct wiggleData *)NULL,
};
/* Droplist menu for custom track visibility: */
static char *ctWigVisMenu[] =
{
"hide",
"dense",
"full",
};
static int ctWigVisMenuSize = sizeof(ctWigVisMenu)/sizeof(char *);
/* Droplist menu for custom track data count: */
static char *ctWigCountMenu[] =
{
"10000",
"100000",
"1000000",
};
static int ctWigCountMenuSize = sizeof(ctWigCountMenu)/sizeof(char *);
struct wiggleStats *wigStatsList[2] =
{
(struct wiggleStats *) NULL,
(struct wiggleStats *) NULL,
};
struct hash *chromsDone[2];
static void printBedEl(struct bed *bedEl)
{
printf("%s\t%u\t%u\t%s\n", bedEl->chrom, bedEl->chromStart,
bedEl->chromEnd, bedEl->name);
}
/********* wiggle compare functions ***********************************/
static boolean wigInRange(int tableId, double value, boolean summaryOnly,
struct wiggle *wiggle)
{
boolean ret = FALSE;
if (summaryOnly)
ret = ((wiggle->lowerLimit <= wigDataConstraint[tableId][1]) &&
(wiggle->lowerLimit+wiggle->dataRange >= wigDataConstraint[tableId][0]));
else
ret = (value >= wigDataConstraint[tableId][0] &&
value <= wigDataConstraint[tableId][1]);
return ret;
}
static boolean wigLessThan(int tableId, double value, boolean summaryOnly,
struct wiggle *wiggle)
{
boolean ret = FALSE;
if (summaryOnly)
ret = (wiggle->lowerLimit < wigDataConstraint[tableId][0]);
else
ret = (value < wigDataConstraint[tableId][0]);
return ret;
}
static boolean wigLessEqual(int tableId, double value, boolean summaryOnly,
struct wiggle *wiggle)
{
boolean ret = FALSE;
if (summaryOnly)
ret = (wiggle->lowerLimit <= wigDataConstraint[tableId][0]);
else
ret = (value <= wigDataConstraint[tableId][0]);
return ret;
}
static boolean wigEqual(int tableId, double value, boolean summaryOnly,
struct wiggle *wiggle)
{
boolean ret = FALSE;
if (summaryOnly)
ret = ((wiggle->lowerLimit < wigDataConstraint[tableId][0]) &&
(wiggle->lowerLimit+wiggle->dataRange > wigDataConstraint[tableId][0]));
else
ret = (value == wigDataConstraint[tableId][0]);
return ret;
}
static boolean wigNotEqual(int tableId, double value, boolean summaryOnly,
struct wiggle *wiggle)
{
boolean ret = FALSE;
if (summaryOnly)
ret = ((wiggle->lowerLimit > wigDataConstraint[tableId][0]) ||
(wiggle->lowerLimit+wiggle->dataRange < wigDataConstraint[tableId][0]));
else
ret = (value != wigDataConstraint[tableId][0]);
return ret;
}
static boolean wigGreaterEqual(int tableId, double value, boolean summaryOnly,
struct wiggle *wiggle)
{
boolean ret = FALSE;
if (summaryOnly)
ret=(wiggle->lowerLimit+wiggle->dataRange >= wigDataConstraint[tableId][0]);
else
ret = (value >= wigDataConstraint[tableId][0]);
return ret;
}
static boolean wigGreaterThan(int tableId, double value, boolean summaryOnly,
struct wiggle *wiggle)
{
boolean ret = FALSE;
if (summaryOnly)
ret = (wiggle->lowerLimit+wiggle->dataRange > wigDataConstraint[tableId][0]);
else
ret = (value > wigDataConstraint[tableId][0]);
return ret;
}
static void showConstraints(char *constraints, int tableId, boolean htmlOutput)
{
boolean foundSome = FALSE;
if (htmlOutput)
printf("
Constraints in effect: ");
if ((constraints != NULL) && (constraints[0] != 0))
{
foundSome = TRUE;
if (htmlOutput)
printf("%s\n", constraints);
else
printf("#\tSQL query constraint: %s\n", constraints);
}
if (wigConstraint[tableId])
{
if (htmlOutput)
if (foundSome)
printf(" AND ");
foundSome = TRUE;
if (sameWord(wigConstraint[tableId],"in range"))
{
if (htmlOutput)
printf("(data value %s [%g , %g])",
wigConstraint[tableId], wigDataConstraint[tableId][0],
wigDataConstraint[tableId][1]);
else
printf("#\tdata value constraint range: %s [%g , %g]\n",
wigConstraint[tableId], wigDataConstraint[tableId][0],
wigDataConstraint[tableId][1]);
}
else
{
if (htmlOutput)
printf("(data value %s %g)",
wigConstraint[tableId], wigDataConstraint[tableId][0]);
else
printf("#\tdata value constraint: %s %g\n",
wigConstraint[tableId], wigDataConstraint[tableId][0]);
}
}
if (htmlOutput)
{
if (foundSome)
printf("
\n");
else
printf("NONE\n");
}
}
void wiggleConstraints(char *cmp, char *pat, int tableIndex)
{
wigConstraint[tableIndex] = cmp;
wiggleCompare[tableIndex] = NULL;
if (strlen(pat)>0)
{
if (sameWord(cmp,"in range"))
{
char *rangeValues[2];
char *clone = cloneString(pat);
int records = 0;
char *comma = strchr(pat,',');
if (comma == (char *)NULL)
records = chopByWhite(clone,rangeValues,2);
else
records = chopByChar(clone,',',rangeValues,2);
if (records == 2)
{
trimSpaces(rangeValues[0]);
trimSpaces(rangeValues[1]);
wigDataConstraint[tableIndex][0] = sqlDouble(rangeValues[0]);
wigDataConstraint[tableIndex][1] = sqlDouble(rangeValues[1]);
if (wigDataConstraint[tableIndex][0] >
wigDataConstraint[tableIndex][1])
{
double d = wigDataConstraint[tableIndex][1];
wigDataConstraint[tableIndex][1] =
wigDataConstraint[tableIndex][0];
wigDataConstraint[tableIndex][0] = d;
}
wiggleCompare[tableIndex] = wigInRange;
}
freeMem(clone);
if (wigDataConstraint[tableIndex][1] ==
wigDataConstraint[tableIndex][0])
errAbort("For \"in range\" constraint, you must give two numbers separated by whitespace or comma.");
}
else
{
wigDataConstraint[tableIndex][0] = sqlDouble(pat);
if (sameWord(cmp,"<")) wiggleCompare[tableIndex] = wigLessThan;
else if (sameWord(cmp,"<=")) wiggleCompare[tableIndex] = wigLessEqual;
else if (sameWord(cmp,"=")) wiggleCompare[tableIndex] = wigEqual;
else if (sameWord(cmp,"!=")) wiggleCompare[tableIndex] = wigNotEqual;
else if (sameWord(cmp,">=")) wiggleCompare[tableIndex]=wigGreaterEqual;
else if (sameWord(cmp,">")) wiggleCompare[tableIndex] = wigGreaterThan;
}
}
}
static void wigPrintRow(struct wiggleStats *wigStats)
{
printf(" %s | \n", wigStats->chrom);
printf("\t %u | \n", wigStats->chromStart+1);
/* display closed coords */
printf("\t %u | \n", wigStats->chromEnd);
printf("\t %u | \n", wigStats->count);
printf("\t %d | \n", wigStats->span);
printf("\t %u | \n", wigStats->count*wigStats->span);
printf("\t %g | \n", wigStats->lowerLimit);
printf("\t %g | \n", wigStats->lowerLimit+wigStats->dataRange);
printf("\t %g | \n", wigStats->dataRange);
printf("\t %g | \n", wigStats->mean);
printf("\t %g | \n", wigStats->variance);
printf("\t %g | \n", wigStats->stddev);
printf("
---|
\n");
}
static void wigPrintStats(struct wiggleStats **wsList, char *chrom)
{
struct wiggleStats *wigStats = (struct wiggleStats *)NULL;
for (wigStats = *wsList; wigStats; wigStats = wigStats->next)
{
if (sameWord(wigStats->chrom,chrom))
wigPrintRow(wigStats);
}
}
/* Check to see if this stats are done for this chrom */
static boolean wigStatsDone(int tableId, char *chrom)
{
if (chromsDone[tableId] == (struct hash *)NULL)
return FALSE;
else if (hashLookup(chromsDone[tableId],chrom))
return TRUE;
else
return FALSE;
}
static void wigMarkDone(int tableId, char *chrom)
{
if ((struct hash *)NULL == chromsDone[tableId])
chromsDone[tableId] = newHash(0);
if ( (struct hashEl *)NULL == hashLookup(chromsDone[tableId],chrom))
hashAdd(chromsDone[tableId],chrom,NULL);
}
void wigMakeBedList(char *database, char *table, char *chrom,
char *constraints, int tableId)
{
char *setting = cartCgiUsualString(cart, "tbWigCount", ctWigCountMenu[1]);
unsigned maxLinesOut = MAX_LINES_OUT;
if (setting != (char *) NULL)
maxLinesOut = sqlUnsigned(setting);
if ( ! wigStatsDone(tableId, chrom))
{
wigData[tableId] = wigFetchData(database, table, chrom, winStart, winEnd,
WIG_ALL_DATA, WIG_DATA_NOT_RETURNED, tableId, wiggleCompare[tableId],
constraints, &bedListWig[tableId], maxLinesOut,
&wigStatsList[tableId]);
wigMarkDone(tableId, chrom);
}
}
void wigDoStats(char *database, char *table, struct slName *chromList,
int tableId, char *constraints)
{
struct slName *chromPtr;
char *db = getTableDb();
struct sqlConnection *conn = hAllocOrConnect(db);
struct sqlResult *sr = (struct sqlResult *)NULL;
char query[256];
char **row = (char **)NULL;
char wigFullTableName[256];
char *setting = cartCgiUsualString(cart, "tbWigCount", ctWigCountMenu[1]);
unsigned maxLinesOut = MAX_LINES_OUT;
int numChroms = 0;
int tableRowsDisplayed = 0;
if (setting != (char *) NULL)
maxLinesOut = sqlUnsigned(setting);
if (tableIsSplit)
{
getFullTableName(wigFullTableName, hDefaultChromDb(db), table);
sqlSafef(query, sizeof(query), "show table status like '%s'", wigFullTableName);
}
else
sqlSafef(query, sizeof(query), "show table status like '%s'", table);
sr = sqlMustGetResult(conn,query);
row = sqlNextRow(sr);
// For some reason BORDER=1 does not work in our web.c nested table scheme.
// So use web.c's trick of using an enclosing table to provide a border.
puts("" "\n"
"
");
puts("");
if (row != NULL)
{
printf("\n");
printf(""
" Database: %s | Table: %s | Last update: %s |
---|
| \n",
database, table, row[11]);
}
else
{
printf(" Database: %s | Table: %s | \n", database,
table);
}
sqlFreeResult(&sr);
hFreeOrDisconnect(&conn);
printf(" Chrom | Data start | ");
printf(" Data end | ");
printf(" # of Data values | Data span | ");
printf(" Bases covered | Minimum | ");
printf(" Maximum | Range | Mean | ");
printf(" Variance | Standard deviation | \n");
numChroms = slCount(chromList);
for (chromPtr=chromList; chromPtr != NULL; chromPtr=chromPtr->next)
{
char *chrom = chromPtr->name;
char wigFullTableName[256];
getFullTableName(wigFullTableName, chrom, table);
if ( ! wigStatsDone(tableId, chrom))
{
boolean dataFetchType = WIG_SUMMARY_ONLY;
if (numChroms == 1)
dataFetchType = WIG_ALL_DATA;
if (wiggleCompare[tableId])
dataFetchType = WIG_ALL_DATA;
if (numChroms > 1)
wigData[tableId] = wigFetchData(database, wigFullTableName, chrom,
winStart, winEnd, dataFetchType, WIG_DATA_NOT_RETURNED, tableId,
wiggleCompare[tableId], constraints, (struct bed **)NULL,
maxLinesOut, &wigStatsList[tableId]);
else
wigData[tableId] = wigFetchData(database, wigFullTableName, chrom,
winStart, winEnd, dataFetchType, WIG_DATA_NOT_RETURNED, tableId,
wiggleCompare[tableId], constraints, (struct bed **)NULL,
0, &wigStatsList[tableId]);
wigMarkDone(tableId, chrom);
}
if (wigStatsDone(tableId, chrom))
{
wigPrintStats(&wigStatsList[tableId], chrom);
if (wigStatsList[tableId] != (struct wiggleStats *) NULL)
++tableRowsDisplayed;
}
else
{
printf(" %s | ", chrom);
printf(" No data | \n");
++tableRowsDisplayed;
}
}
/* No rows in table, indicate this no result */
if (!tableRowsDisplayed)
puts(" No data found matching this request | ");
printf(" \n");
puts(" |
");
} /* void wigDoStats() */
void doWiggleCtOptions(boolean doCt)
{
struct hTableInfo *hti = getOutputHti();
char *table = getTableName();
char *table2 = getTable2Name();
char *op = cgiOptionalString("tbIntersectOp");
char *db = getTableDb();
char *outputType = cgiUsualString("outputType", cgiString("phase"));
char *phase = (existsAndEqual("phase", getOutputPhase) ?
cgiString("outputType") : cgiString("phase"));
char *setting = NULL;
char buf[256];
char *constraints = constrainFields(NULL);
saveOutputOptionsState();
saveIntersectOptionsState();
webStart(cart, "Table Browser: %s %s: %s", hOrganism(database), freezeName,
phase);
checkTableExists(fullTableName);
printf("");
webEnd();
} /* void doWiggleCtOptions(boolean doCt) */
static void fileConstraints(char *constraints, int tableId, FILE *f)
{
if (constraints)
fprintf(f, "#\tSQL query constraint: %s\n", constraints);
if (wigConstraint[tableId])
{
if (sameWord(wigConstraint[tableId],"in range"))
fprintf(f,"#\tdata value constraint range: %s [%g , %g]\n",
wigConstraint[tableId], wigDataConstraint[tableId][0],
wigDataConstraint[tableId][1]);
else
fprintf(f,"#\tdata value constraint: %s %g\n",
wigConstraint[tableId], wigDataConstraint[tableId][0]);
}
}
void doGetWiggleData(boolean doCt)
/* Find wiggle data and display it */
{
struct slName *chromList, *chromPtr;
char *db = getTableDb();
char *table = getTableName();
struct wiggleData *wigData = (struct wiggleData *) NULL;
struct wiggleData *wdPtr = (struct wiggleData *) NULL;
struct trackDb *tdb = (struct trackDb *)NULL;
char *track = getTrackName();
unsigned linesOutput = 0;
boolean doCtHdr = (cartCgiUsualBoolean(cart, "tbDoCustomTrack", FALSE) || doCt);
char *constraints;
char *setting = cartCgiUsualString(cart, "tbWigCount", ctWigCountMenu[1]);
unsigned maxLinesOut = MAX_LINES_OUT;
char *longLabel = cloneString("User Supplied Track");
char *ctDesc = cgiUsualString("tbCtDesc", table);
char *ctName = cgiUsualString("tbCtName", table);
char *ctVis = cgiUsualString("tbCtVis", "hide");
char *ctUrl = cgiUsualString("tbCtUrl", "");
struct customTrack *ctNew = NULL;
char tableName[128];
char *visibility;
int visNum = 0;
boolean wigBED = FALSE;
struct bed *bedList = NULL;
FILE *wigAsciiFH = (FILE *) NULL;
if (! sameString(customTrackPseudoDb, db))
{
struct sqlConnection *conn = hAllocOrConnect(db);
tdb = hMaybeTrackInfo(conn, track);
hFreeOrDisconnect(&conn);
}
if (setting != (char *) NULL)
maxLinesOut = sqlUnsigned(setting);
setting = cartCgiUsualString(cart, "tbWigDataType", "wigData");
if ( sameString(setting, "bedData") )
wigBED = TRUE;
saveOutputOptionsState();
saveIntersectOptionsState();
constraints = constrainFields(NULL);
if ((constraints != NULL) && (constraints[0] == 0))
constraints = NULL;
if (!doCt)
{
printf("Content-Type: text/plain\n\n");
webStartText();
}
if (differentWord(ctName,table) )
snprintf(tableName, sizeof(tableName), "%s", ctName);
else
snprintf(tableName, sizeof(tableName), "tb_%s", table);
if (ctDesc != (char *)NULL)
{
freeMem(longLabel);
longLabel = cloneString(ctDesc);
}
if (ctVis != (char *)NULL)
visibility = cloneString(ctVis);
else
visibility = cloneString("hide");
visNum = (int) hTvFromStringNoAbort(visibility);
if (visNum < 0)
visNum = 0;
if (allGenome)
chromList = getOrderedChromList();
else
chromList = newSlName(chrom);
if (doCtHdr && wigBED && !doCt)
{
printf("track name=\"%s\" description=\"%s\" "
"visibility=%s\n", tableName, longLabel, visibility);
showConstraints(constraints, WIG_TABLE_1, FALSE);
}
if (doCt)
{
int fields=0;
if (wigBED)
fields=4;
ctNew = newCT(tableName, longLabel, visNum, ctUrl, fields);
if (wigBED)
ctNew->wiggle = FALSE;
else
{
struct tempName tn;
makeTempName(&tn, "hgtct", ".wig");
ctNew->wigFile = cloneString(tn.forCgi);
makeTempName(&tn, "hgtct", ".wib");
ctNew->wibFile = cloneString(tn.forCgi);
makeTempName(&tn, "hgtct", ".wia");
ctNew->wigAscii = cloneString(tn.forCgi);
wigAsciiFH = mustOpen(ctNew->wigAscii, "w");
#if defined(DEBUG) /* dbg */
/* allow file readability for debug */
chmod(ctNew->wigAscii, 0666);
#endif
ctNew->wiggle = TRUE;
}
}
for (chromPtr=chromList; chromPtr != NULL && (linesOutput < maxLinesOut);
chromPtr=chromPtr->next)
{
char *chrom = chromPtr->name;
char wigFullTableName[256];
int bedLength = 0;
getFullTableName(wigFullTableName, chrom, table);
if (wigBED)
{
wigData = wigFetchData(database, table, chrom, winStart, winEnd,
WIG_ALL_DATA, WIG_DATA_NOT_RETURNED, WIG_TABLE_1,
wiggleCompare[WIG_TABLE_1], constraints,
&bedListWig[WIG_TABLE_1], maxLinesOut,
(struct wiggleStats **)NULL);
wigMarkDone(WIG_TABLE_1, chrom);
bedLength = slCount(bedListWig[WIG_TABLE_1]);
}
else
{
wigData = wigFetchData(database, table, chrom, winStart, winEnd,
WIG_ALL_DATA, WIG_RETURN_DATA, WIG_TABLE_1,
wiggleCompare[WIG_TABLE_1], constraints,
(struct bed **)NULL, maxLinesOut,
(struct wiggleStats **)NULL);
wigMarkDone(WIG_TABLE_1, chrom);
}
if (wigData)
{
unsigned span = 0;
char *chrom = (char *) NULL;
unsigned char colorR, colorG, colorB;
unsigned char altColorR, altColorG, altColorB;
float priority;
int wordCount;
char *words[128];
char *trackType = (char *) NULL;
boolean nextSpan = FALSE;
if (tdb && tdb->type)
{
char *typeLine = cloneString(tdb->type);
if (ctDesc == (char *)NULL)
{
freeMem(longLabel);
longLabel = cloneString(tdb->longLabel);
}
priority = tdb->priority;
wordCount = chopLine(typeLine,words);
if (wordCount > 0)
trackType = words[0];
colorR = tdb->colorR; colorG = tdb->colorG; colorB = tdb->colorB;
altColorR = tdb->altColorR; altColorG = tdb->altColorG;
altColorB = tdb->altColorB;
colorR = colorG = colorB = 0;
altColorR = altColorG = altColorB = 128;
}
else
{
priority = 42;
if (ctDesc == (char *)NULL)
{
freeMem(longLabel);
longLabel = cloneString("User Supplied Track");
}
colorR = colorG = colorB = 255;
altColorR = altColorG = altColorB = 128;
}
if (doCt)
{
ctNew->tdb->longLabel = longLabel;
}
if (doCtHdr && (!wigBED))
{
if (doCt)
{
struct dyString *wigSettings = newDyString(0);
ctNew->tdb->priority = priority;
ctNew->tdb->colorR = colorR;
ctNew->tdb->colorG = colorB;
ctNew->tdb->colorB = colorB;
ctNew->tdb->altColorR = altColorR;
ctNew->tdb->altColorG = altColorB;
ctNew->tdb->altColorB = altColorB;
/* more settings to be done */
dyStringPrintf(wigSettings,
"type='wiggle_0'\twigFile='%s'\twibFile='%s'",
ctNew->wigFile, ctNew->wibFile);
ctNew->tdb->settings = dyStringCannibalize(&wigSettings);
fileConstraints(constraints, WIG_TABLE_1, wigAsciiFH);
}
else
{
printf("track type=wiggle_0 name=%s description=\"%s\" "
"visibility=%s color=%d,%d,%d altColor=%d,%d,%d "
"priority=%g\n", tableName, longLabel, visibility,
colorR, colorG, colorB, altColorR, altColorG, altColorB,
priority);
showConstraints(constraints, WIG_TABLE_1, FALSE);
}
}
for (wdPtr = wigData; (linesOutput < maxLinesOut) &&
(wdPtr != (struct wiggleData *) NULL); wdPtr= wdPtr->next)
{
if ((chrom == (char *) NULL) || differentWord(chrom,wdPtr->chrom))
{
if (!(doCtHdr | wigBED))
{
if (!doCt)
printf("#\t");
}
if (!wigBED)
{
if (doCt)
fprintf(wigAsciiFH,
"variableStep chrom=%s span=%u\n",
wdPtr->chrom, wdPtr->span);
else
printf("variableStep chrom=%s span=%u\n",
wdPtr->chrom, wdPtr->span);
}
chrom = wdPtr->chrom;
span = wdPtr->span;
}
if (span != wdPtr->span)
{
if (!(doCtHdr | wigBED))
printf("#\t");
if (!wigBED)
{
if (doCt)
fprintf(wigAsciiFH,
"variableStep chrom=%s span=%u\n",
wdPtr->chrom, wdPtr->span);
else
printf("variableStep chrom=%s span=%u\n",
wdPtr->chrom, wdPtr->span);
}
span = wdPtr->span;
}
if (wdPtr->data)
{
struct wiggleDatum *wd = wdPtr->data;
int i;
for (i = 0; (!nextSpan) && (linesOutput < maxLinesOut) &&
(i < wdPtr->count); ++i, ++wd)
{
if (doCt)
fprintf(wigAsciiFH, "%u\t%g\n",
wd->chromStart+1, wd->value);
else
printf("%u\t%g\n", wd->chromStart+1, wd->value);
++linesOutput;
}
}
else if (bedLength > 0)
{
struct bed *bedEl = bedListWig[WIG_TABLE_1];
for ( ; linesOutput < maxLinesOut && bedEl;
bedEl = bedEl->next)
{
if (doCt)
{
struct bed *newBed = cloneBed(bedEl);
slAddHead(&bedList, newBed);
}
else
printBedEl(bedEl);
++linesOutput;
}
if (doCt)
bedFreeList(&bedListWig[WIG_TABLE_1]);
bedLength = 0;
}
}
wigFreeData(&wigData);
}
}
if ((ctNew != NULL) && (bedList != NULL))
{
slReverse(&bedList);
ctNew->bedList = bedList;
}
if ((ctNew != NULL) && ((ctNew->bedList != NULL) || (ctNew->wigAscii != NULL)))
{
/* Load existing custom tracks and add this new one: */
struct customTrack *ctList = getCustomTracks();
slAddHead(&ctList, ctNew);
carefulClose(&wigAsciiFH);
/* Save the custom tracks out to file (overwrite the old file): */
customTracksSaveCart(cart, ctList);
}
if (doCt)
{
char browserUrl[128];
char headerText[256];
int redirDelay = 5;
if (linesOutput < 1)
{
printf("Content-Type: text/plain\n\n");
webStartText();
printf("#\tno results returned from query\n");
webEnd();
}
else
{
safef(browserUrl, sizeof(browserUrl),
"%s?db=%s&position=%s:%d-%d",
hgTracksName(), database, chrom, winStart, winEnd);
safef(headerText, sizeof(headerText),
"",
redirDelay, browserUrl);
webStartHeader(cart, headerText,
"Table Browser: %s %s: %s", hOrganism(database),
freezeName, getCtPhase);
printf("You will be automatically redirected to the genome browser in\n"
"%d seconds, or you can
\n"
"click here to continue.\n",
redirDelay, browserUrl);
webEnd();
}
}
else
{
if (linesOutput < 1)
{
printf("#\tno results returned from query\n");
}
else if (linesOutput >= maxLinesOut)
printf("#\tmaximum data output of %u lines reached\n", maxLinesOut);
webEnd();
}
} /* void doGetWiggleData(boolean doCt) */