/* hgNear - gene sorter. */ #include "common.h" #include "linefile.h" #include "hash.h" #include "dystring.h" #include "obscure.h" #include "portable.h" #include "cheapcgi.h" #include "memalloc.h" #include "jksql.h" #include "htmshell.h" #include "hVarSubst.h" #include "cart.h" #include "dbDb.h" #include "hdb.h" #include "hui.h" #include "web.h" #include "ra.h" #include "hgColors.h" #include "hgNear.h" #include "versionInfo.h" char *excludeVars[] = { "submit", "Submit", idPosVarName, NULL }; /* The excludeVars are not saved to the cart. (We also exclude * any variables that start "near.do.") */ /* ---- Global variables. ---- */ struct cart *cart; /* This holds cgi and other variables between clicks. */ struct hash *oldVars = NULL; /* The cart vars before new cgi stuff added. */ char *database; /* Name of genome database - hg15, mm3, or the like. */ char *genome; /* Name of genome - mouse, human, etc. */ char *groupOn; /* Current grouping strategy. */ int displayCount; /* Number of items to display. */ char *displayCountString; /* Ascii version of display count, including 'all'. */ struct hash *genomeSettings; /* Genome-specific settings from settings.ra. */ struct hash *columnHash; /* Hash of active columns keyed by name. */ struct genePos *curGeneId; /* Identity of current gene. */ int kgVersion = KG_UNKNOWN; /* KG version */ /* ---- General purpose helper routines. ---- */ int genePosCmpName(const void *va, const void *vb) /* Sort function to compare two genePos by name. */ { const struct genePos *a = *((struct genePos **)va); const struct genePos *b = *((struct genePos **)vb); return strcmp(a->name, b->name); } int genePosCmpPos(const void *va, const void *vb) /* Sort function to compare two genePos by chrom,start. */ { const struct genePos *a = *((struct genePos **)va); const struct genePos *b = *((struct genePos **)vb); int diff = strcmp(a->chrom, b->chrom); if (diff == 0) diff = a->start - b->start; return diff; } void genePosFillFrom5(struct genePos *gp, char **row) /* Fill in genePos from row containing ascii version of * name/chrom/start/end/protein. */ { gp->name = cloneString(row[0]); gp->chrom = cloneString(row[1]); gp->start = sqlUnsigned(row[2]); gp->end = sqlUnsigned(row[3]); gp->protein = cloneString(row[4]); gp->distance = genePosTooFar; } int genePosCmpDistance(const void *va, const void *vb) /* Compare to sort based on distance. */ { const struct genePos *a = *((struct genePos **)va); const struct genePos *b = *((struct genePos **)vb); float diff = a->distance - b->distance; if (diff > 0) return 1; else if (diff < 0) return -1; else { return strcmp(a->protein, b->protein); } } boolean wildMatchAny(char *word, struct slName *wildList) /* Return TRUE if word matches any thing in wildList. */ { struct slName *w; for (w = wildList; w != NULL; w = w->next) if (wildMatch(w->name, word) ) return TRUE; return FALSE; } boolean wildMatchAll(char *word, struct slName *wildList) /* Return TRUE if word matches all things in wildList. */ { struct slName *w; for (w = wildList; w != NULL; w = w->next) if (!wildMatch(w->name, word) ) return FALSE; return TRUE; } boolean wildMatchList(char *word, struct slName *wildList, boolean orLogic) /* Return TRUE if word matches things in wildList. */ { if (orLogic) return wildMatchAny(word, wildList); else return wildMatchAll(word, wildList); } boolean anyRealInCart(struct cart *cart, char *wild) /* Return TRUE if variables are set matching wildcard. */ { struct hashEl *varList = NULL, *var; boolean ret = FALSE; varList = cartFindLike(cart, wild); for (var = varList; var != NULL; var = var->next) { char *s = var->val; if (s != NULL) { s = trimSpaces(s); if (s[0] != 0) { ret = TRUE; break; } } } hashElFreeList(&varList); return ret; } void fixSafariSpaceInQuotes(char *s) /* Safari on the Mac changes a space (ascii 32) to a * ascii 160 if it's inside of a single-quote in a * text input box!? This tuns it back to a 32. */ { unsigned char c; while ((c = *s) != 0) { if (c == 160) *s = 32; ++s; } } void makeTitle(char *title, char *helpName) /* Print main menu and the title bar. */ { char buf[1024]; if(!helpName) helpName = "hgNearHelp.html"; safef(buf, sizeof(buf), "../goldenPath/help/%s", helpName); setContextSpecificHelp(buf, NULL); cartWebStart(cart, database, "%s", title); } /* ---- Some helper routines for order methods. ---- */ char *orderSetting(struct order *ord, char *name, char *defaultVal) /* Return value of named setting in order, or default if it doesn't exist. */ { char *result = hashFindVal(ord->settings, name); if (result == NULL) result = defaultVal; return result; } char *orderRequiredSetting(struct order *ord, char *name) /* Return value of named setting. Abort if it doesn't exist. */ { char *result = hashFindVal(ord->settings, name); if (result == NULL) errAbort("Missing required %s field in %s record of orderDb.ra", name, ord->name); return result; } int orderIntSetting(struct order *ord, char *name, int defaultVal) /* Return value of named integer setting or default if it doesn't exist. */ { char *result = hashFindVal(ord->settings, name); if (result == NULL) return defaultVal; return atoi(result); } boolean orderSettingExists(struct order *ord, char *name) /* Return TRUE if setting exists in column. */ { return hashFindVal(ord->settings, name) != NULL; } /* ---- Some helper routines for column methods. ---- */ char *columnSetting(struct column *col, char *name, char *defaultVal) /* Return value of named setting in column, or default if it doesn't exist. */ { char *result = hashFindVal(col->settings, name); if (result == NULL) result = defaultVal; return result; } char *columnRequiredSetting(struct column *col, char *name) /* Return value of named setting. Abort if it doesn't exist. */ { char *result = hashFindVal(col->settings, name); if (result == NULL) errAbort("Missing required %s field in %s record of columnDb.ra", name, col->name); return result; } int columnSettingInt(struct column *col, char *name, int defaultVal) /* Return value of named integer setting or default if it doesn't exist. */ { char *result = hashFindVal(col->settings, name); if (result == NULL) return defaultVal; return atoi(result); } boolean columnSettingExists(struct column *col, char *name) /* Return TRUE if setting exists in column. */ { return hashFindVal(col->settings, name) != NULL; } struct sqlConnection *hgFixedConn() /* Return connection to hgFixed database. * This is effectively a global, but not * opened until needed. */ { static struct sqlConnection *conn = NULL; if (conn == NULL) conn = sqlConnect("hgFixed"); return conn; } char *colVarName(struct column *col, char *prefix) /* Return variable name prefix.col->name. This is just a static * variable, so don't nest these calls*/ { static char name[64]; safef(name, sizeof(name), "%s%s", prefix, col->name); return name; } void colButton(struct column *col, char *prefix, char *label) /* Make a button named prefix.col->name with given label. */ { static char name[64]; safef(name, sizeof(name), "%s%s", prefix, col->name); cgiMakeButton(name, label); } struct column *colButtonPressed(struct column *colList, char *prefix) /* See if a button named prefix.column is pressed for some * column, and if so return the column, else NULL. */ { static char pattern[64]; char colName[64]; char *match; safef(pattern, sizeof(pattern), "%s*", prefix); match = cartFindFirstLike(cart, pattern); if (match == NULL) return NULL; /* Construct column name. If variable is from an file upload * there __filename suffix attached that we need to remove. */ safef(colName, sizeof(colName), "%s", match + strlen(prefix)); if (endsWith(colName, "__filename")) { int newLen = strlen(colName) - strlen("__filename"); colName[newLen] = 0; } return findNamedColumn(colName); } static char *keyFileName(struct column *col) /* Return key file name for this column. Return * NULL if no key file. */ { char *fileName = advFilterVal(col, "keyFile"); if (fileName == NULL) return NULL; if (!fileExists(fileName)) { cartRemove(cart, advFilterName(col, "keyFile")); return NULL; } return fileName; } struct slName *keyFileList(struct column *col) /* Make up list from key file for this column. * return NULL if no key file. */ { char *fileName = keyFileName(col); char *buf; struct slName *list; if (fileName == NULL) return NULL; readInGulp(fileName, &buf, NULL); list = stringToSlNames(buf); freez(&buf); return list; } static struct hash *upcHashWordsInFile(char *fileName, int hashSize) /* Create a hash of space delimited uppercased words in file. */ { struct hash *hash = newHash(hashSize); struct lineFile *lf = lineFileOpen(fileName, TRUE); char *line, *word; while (lineFileNext(lf, &line, NULL)) { while ((word = nextQuotedWord(&line)) != NULL) { touppers(word); hashAdd(hash, word, NULL); } } lineFileClose(&lf); return hash; } struct hash *keyFileHash(struct column *col) /* Make up a hash from key file for this column. * Return NULL if no key file. */ { char *fileName = keyFileName(col); if (fileName == NULL) return NULL; return upcHashWordsInFile(fileName, 16); } char *cellLookupVal(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* Get a field in a table defined by col->table, col->keyField, * col->valField. If an xrefLookup is specified in col->settings, * use that to look up an alternate name for the result. */ { char *xrefDb = hashFindVal(col->settings, "xrefDb"); char *xrefTable = hashFindVal(col->settings, "xrefTable"); char *xrefNameField = hashFindVal(col->settings, "xrefNameField"); char *xrefAliasField = hashFindVal(col->settings, "xrefAliasField"); char query[1024]; if (xrefDb) safef(query, sizeof(query), "select %s.%s.%s " "from %s.%s, %s " "where %s.%s = '%s' " "and %s.%s = %s.%s.%s;", xrefDb, xrefTable, xrefAliasField, xrefDb, xrefTable, col->table, col->table, col->keyField, gp->name, col->table, col->valField, xrefDb, xrefTable, xrefNameField); else safef(query, sizeof(query), "select %s from %s where %s = '%s'", col->valField, col->table, col->keyField, gp->name); return sqlQuickString(conn, query); } char *lookupItemUrlVal(struct column *col, char *sVal, struct sqlConnection *conn) { char query[512]; safef(query, sizeof(query), col->itemUrlQuery, sVal); return sqlQuickString(conn, query); } void cellSimplePrintExt(struct column *col, struct genePos *gp, struct sqlConnection *conn, boolean lookupForUrl) /* This just prints one field from table. */ { char *s = col->cellVal(col, gp, conn); hPrintf(""); if (s == NULL) { hPrintf("n/a"); } else { if (col->selfLink) { selfAnchorId(gp); hPrintEncodedNonBreak(s); hPrintf(""); } else if (col->itemUrl != NULL) { hPrintf("name; if (lookupForUrl) sVal = s; if (col->itemUrlQuery) sVal = lookupItemUrlVal(col, sVal, conn); hPrintf(col->itemUrl, sVal); if (col->itemUrlQuery) freez(&sVal); if (col->useHgsid) hPrintf("&%s", cartSidUrlString(cart)); if (col->urlChromVar) hPrintf("&%s=%s", col->urlChromVar, gp->chrom); if (col->urlStartVar) hPrintf("&%s=%d", col->urlStartVar, gp->start); if (col->urlEndVar) hPrintf("&%s=%d", col->urlEndVar, gp->end); if (col->urlOtherGeneVar) hPrintf("&%s=%s", col->urlOtherGeneVar, curGeneId->name); hPrintf("\""); if (!col->useHgsid) hPrintf(" TARGET=_blank"); hPrintf(">"); hPrintEncodedNonBreak(s); hPrintf(""); } else { hPrintEncodedNonBreak(s); } freeMem(s); } hPrintf(""); } void cellSimplePrint(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* This just prints one field from table. */ { cellSimplePrintExt(col, gp, conn, TRUE); } void cellSimplePrintNoLookupUrl(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* This just prints one field from table using gp->name for * itemUrl. */ { cellSimplePrintExt(col, gp, conn, FALSE); } static void hPrintSpaces(int count) /* Print count number of spaces. */ { while (--count >= 0) hPrintf(" "); } char *colInfoUrl(struct column *col) /* Return URL to get column info. freeMem this when done. */ { char *labelUrl; if ((labelUrl = columnSetting(col, "labelUrl", NULL)) != NULL) return labelUrl; else { char url[512]; char *encoded = cgiEncode(col->name); safef(url, sizeof(url), "../cgi-bin/hgNear?%s&%s=%s", cartSidUrlString(cart), colInfoVarName, encoded); freeMem(encoded); return cloneString(url); } } void colInfoAnchor(struct column *col) /* Print anchor tag that leads to column info page. */ { char *url = colInfoUrl(col); hPrintf("", url); freeMem(url); } void colInfoLink(struct column *col) /* Print link to column. */ { colInfoAnchor(col); hPrintf("%s", col->shortLabel); } void labelSimplePrint(struct column *col) /* This just prints cell->shortLabel. If colWidth is * set it will add spaces, center justifying it. */ { int colWidth = columnSettingInt(col, "colWidth", 0); hPrintf("
");
/* The 
 above helps Internet Explorer avoid wrapping
 * in the label column, which helps us avoid wrapping in
 * the data columns below.  Wrapping in the data columns
 * makes the expression display less effective so we try
 * to minimize it.  -jk */
if (colWidth == 0)
    {
    colInfoLink(col);
    }
else
    {
    int labelLen = strlen(col->shortLabel);
    int diff = colWidth - labelLen;
    if (diff < 0) diff = 0;
    colInfoLink(col);
    hPrintSpaces(diff);
    }
hPrintf("
"); } void selfAnchorSearch(struct genePos *gp) /* Print self anchor to given search term. */ { hPrintf("", cartSidUrlString(cart), searchVarName, gp->name); } void selfAnchorId(struct genePos *gp) /* Print self anchor to given id. */ { hPrintf("name); if (gp->chrom != NULL) hPrintf("&%s=%s:%d-%d", idPosVarName, gp->chrom, gp->start+1, gp->end); hPrintf("\">"); } void cellSelfLinkPrint(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* Print self and hyperlink to make this the search term. */ { char *s = col->cellVal(col, gp, conn); if (s == NULL) s = cloneString("n/a"); hPrintf(""); selfAnchorId(gp); hPrintEncodedNonBreak(s); hPrintf(""); freeMem(s); } struct genePos *weedUnlessInHash(struct genePos *inList, struct hash *hash) /* Return input list with stuff not in hash removed. */ { struct genePos *outList = NULL, *gp, *next; for (gp = inList; gp != NULL; gp = next) { next = gp->next; if (hashLookup(hash, gp->name)) { slAddHead(&outList, gp); } } slReverse(&outList); return outList; } static boolean alwaysExists(struct column *col, struct sqlConnection *conn) /* We always exist. */ { return TRUE; } boolean simpleTableExists(struct column *col, struct sqlConnection *conn) /* This returns true if col->table exists. */ { return sqlTableExists(conn, col->table); } static char *noVal(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* Return not-available value. */ { return cloneString("n/a"); } static int oneColumn(struct column *col) /* Return that we have single column. */ { return 1; } void columnDefaultMethods(struct column *col) /* Set up default methods. */ { col->exists = alwaysExists; col->cellVal = noVal; col->cellPrint = cellSimplePrint; col->labelPrint = labelSimplePrint; col->tableColumns = oneColumn; } /* ---- Debugging column ---- */ static boolean debugExists(struct column *col, struct sqlConnection *conn) /* Return TRUE if we are on hgwdev. */ { char *host = getHost(); return startsWith("hgwdev", host); } char *debugCellVal(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* Return value for debugging column. */ { char buf[32]; safef(buf, sizeof(buf), "%f", gp->distance); return cloneString(buf); } void debugCellPrint(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* Print value including favorite hyperlink in debug column. */ { hPrintf("", cartSidUrlString(cart), gp->name, gp->chrom, gp->start, gp->end); hPrintf("%f", gp->distance); hPrintf(""); } void setupColumnDebug(struct column *col, char *parameters) /* Set up a column that displays the geneId (accession) */ { col->exists = debugExists; col->cellVal = debugCellVal; col->cellPrint = debugCellPrint; } /* ---- Accession column ---- */ static char *accVal(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* Return clone of geneId */ { return cloneString(gp->name); } struct genePos *accAdvFilter(struct column *col, struct sqlConnection *conn, struct genePos *list) /* Do advanced filter on accession. */ { char *wild = advFilterVal(col, "wild"); struct hash *keyHash = keyFileHash(col); if (keyHash != NULL) { struct genePos *newList = NULL, *next, *gp; for (gp = list; gp != NULL; gp = next) { next = gp->next; if (hashLookupUpperCase(keyHash, gp->name)) { slAddHead(&newList, gp); } } slReverse(&newList); list = newList; } if (wild != NULL) { boolean orLogic = advFilterOrLogic(col, "logic", TRUE); struct genePos *newList = NULL, *next, *gp; struct slName *wildList = stringToSlNames(wild); for (gp = list; gp != NULL; gp = next) { next = gp->next; if (wildMatchList(gp->name, wildList, orLogic)) { slAddHead(&newList, gp); } } slReverse(&newList); list = newList; } hashFree(&keyHash); return list; } void setupColumnAcc(struct column *col, char *parameters) /* Set up a column that displays the geneId (accession) */ { col->cellVal = accVal; col->filterControls = lookupAdvFilterControls; col->advFilter = accAdvFilter; } /* ---- Number column ---- */ static char *numberVal(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* Return incrementing number. */ { static int ix = 0; char buf[15]; ++ix; safef(buf, sizeof(buf), "%d", ix); return cloneString(buf); } void setupColumnNum(struct column *col, char *parameters) /* Set up column that displays index in displayed list. */ { col->cellVal = numberVal; col->cellPrint = cellSelfLinkPrint; } /* ---- Simple table lookup type columns ---- */ struct searchResult *lookupTypeSimpleSearch(struct column *col, struct sqlConnection *conn, char *search) /* Search lookup type column. */ { struct dyString *query = dyStringNew(512); char *searchHow = columnSetting(col, "search", "exact"); struct sqlConnection *searchConn = hAllocConn(database); struct sqlResult *sr; char **row; struct searchResult *resList = NULL, *res; dyStringPrintf(query, "select %s,%s from %s where %s ", col->keyField, col->valField, col->table, col->valField); if (sameString(searchHow, "fuzzy")) dyStringPrintf(query, "like '%%%s%%'", search); else if (sameString(searchHow, "prefix")) dyStringPrintf(query, "like '%s%%'", search); else dyStringPrintf(query, " = '%s'", search); sr = sqlGetResult(searchConn, query->string); while ((row = sqlNextRow(sr)) != NULL) { AllocVar(res); res->gp.name = cloneString(row[0]); if (!sameString(searchHow, "fuzzy")) res->matchingId = cloneString(row[1]); slAddHead(&resList, res); } /* Clean up and go home. */ sqlFreeResult(&sr); hFreeConn(&searchConn); dyStringFree(&query); slReverse(&resList); return resList; } void lookupAdvFilterControls(struct column *col, struct sqlConnection *conn) /* Print out controls for advanced filter on lookup column. */ { char *fileName = advFilterVal(col, "keyFile"); hPrintf("%s search (including * and ? wildcards):", col->shortLabel); advFilterRemakeTextVar(col, "wild", 18); hPrintf("
\n"); hPrintf("Include if "); advFilterAnyAllMenu(col, "logic", TRUE); hPrintf("words in search term match.
"); if (!columnSetting(col, "noKeys", NULL)) { hPrintf("Limit to items (no wildcards) in list: "); advFilterKeyPasteButton(col); hPrintf(" "); advFilterKeyUploadButton(col); hPrintf(" "); if (fileName != NULL) { if (fileExists(fileName)) { int count = countWordsInFile(fileName); advFilterKeyClearButton(col); hPrintf("
\n"); if (count == 1) hPrintf("(There is currently 1 item in the list.)"); else hPrintf("(There are currently %d items in the list.)", count); } else { cartRemove(cart, advFilterName(col, "keyFile")); } } } } struct genePos *lookupAdvFilter(struct column *col, struct sqlConnection *conn, struct genePos *list) /* Do advanced filter on position. */ { char *wild = advFilterVal(col, "wild"); struct hash *keyHash = keyFileHash(col); if (wild != NULL || keyHash != NULL) { boolean orLogic = advFilterOrLogic(col, "logic", TRUE); struct hash *hash = newHash(17); char query[256]; struct sqlResult *sr; char **row; struct slName *wildList = stringToSlNames(wild); safef(query, sizeof(query), "select %s,%s from %s", col->keyField, col->valField, col->table); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { if (keyHash == NULL || hashLookupUpperCase(keyHash, row[1])) { if (wildList == NULL || wildMatchList(row[1], wildList, orLogic)) hashAdd(hash, row[0], NULL); } } list = weedUnlessInHash(list, hash); sqlFreeResult(&sr); hashFree(&hash); } hashFree(&keyHash); return list; } void setupColumnLookup(struct column *col, char *parameters) /* Set up column that just looks up one field in a table * keyed by the geneId. */ { char *xrefLookup = cloneString(hashFindVal(col->settings, "xrefLookup")); col->table = cloneString(nextWord(¶meters)); col->keyField = cloneString(nextWord(¶meters)); col->valField = cloneString(nextWord(¶meters)); if (col->valField == NULL) errAbort("Not enough fields in type lookup for %s", col->name); col->exists = simpleTableExists; col->cellVal = cellLookupVal; if (columnSetting(col, "search", NULL)) col->simpleSearch = lookupTypeSimpleSearch; col->filterControls = lookupAdvFilterControls; col->advFilter = lookupAdvFilter; if (isNotEmpty(xrefLookup)) { char *xrefTable = nextWord(&xrefLookup); char *xrefNameField = nextWord(&xrefLookup); char *xrefAliasField = nextWord(&xrefLookup); if (isNotEmpty(xrefAliasField)) { char *xrefOrg = hashFindVal(col->settings, "xrefOrg"); char *xrefDb; if (xrefOrg) xrefDb = hDefaultDbForGenome(xrefOrg); else xrefDb = cloneString(database); struct sqlConnection *xrefConn = hAllocConn(xrefDb); if (sqlTableExists(xrefConn, xrefTable)) { /* These are the column settings that will be used by * cellLookupVal, so it doesn't have to parse xrefLookup and * query for table existence for each cell. */ hashAdd(col->settings, "xrefDb", xrefDb); hashAdd(col->settings, "xrefTable", xrefTable); hashAdd(col->settings, "xrefNameField", xrefNameField); hashAdd(col->settings, "xrefAliasField", xrefAliasField); } hFreeConn(&xrefConn); } } } /* ---- Distance table type columns ---- */ static char *cellDistanceVal(struct column *col, struct genePos *gp, struct sqlConnection *conn) /* Get a field in a table defined by col->table, col->keyField, col->valField. */ { char query[512]; struct sqlResult *sr; char **row; char *res = NULL; safef(query, sizeof(query), "select %s from %s where %s = '%s' and %s = '%s'", col->valField, col->table, col->keyField, gp->name, col->curGeneField, curGeneId->name); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) res = cloneString(row[0]); sqlFreeResult(&sr); return res; } void minMaxAdvFilterControls(struct column *col, struct sqlConnection *conn) /* Print out controls for min/max advanced filter. */ { hPrintf("minimum: "); advFilterRemakeTextVar(col, "min", 8); hPrintf(" maximum: "); advFilterRemakeTextVar(col, "max", 8); } struct genePos *advFilterFromQuery(struct sqlConnection *conn, char *query, struct genePos *list) /* Return list of genes from list that are returned by query */ { struct hash *passHash = newHash(16); /* Hash of genes that pass. */ struct sqlResult *sr = sqlGetResult(conn, query); char **row; while ((row = sqlNextRow(sr)) != NULL) hashAdd(passHash, row[0], NULL); list = weedUnlessInHash(list, passHash); sqlFreeResult(&sr); hashFree(&passHash); return list; } struct genePos *distanceAdvFilter(struct column *col, struct sqlConnection *conn, struct genePos *list) /* Do advanced filter on distance type. */ { char *minString = advFilterVal(col, "min"); char *maxString = advFilterVal(col, "max"); char *name = NULL; if (curGeneId) { name = curGeneId->name; } else { name = cartString(cart, searchVarName); } if (minString != NULL || maxString != NULL) { struct dyString *dy = newDyString(512); dyStringPrintf(dy, "select %s from %s where", col->keyField, col->table); dyStringPrintf(dy, " %s='%s'", col->curGeneField, name); if (minString) dyStringPrintf(dy, " and %s >= %s", col->valField, minString); if (maxString) dyStringPrintf(dy, " and %s <= %s", col->valField, maxString); list = advFilterFromQuery(conn, dy->string, list); dyStringFree(&dy); } return list; } void distanceTypeMethods(struct column *col, char *table, char *curGene, char *otherGene, char *valField) /* Set up a column that looks up a field in a distance matrix * type table such as the expression or homology tables. */ { col->table = cloneString(table); col->keyField = cloneString(otherGene); col->valField = cloneString(valField); col->curGeneField = cloneString(curGene); col->exists = simpleTableExists; col->cellVal = cellDistanceVal; col->cellPrint = cellSimplePrintNoLookupUrl; col->filterControls = minMaxAdvFilterControls; col->advFilter = distanceAdvFilter; } void setupColumnDistance(struct column *col, char *parameters) /* Set up a column that looks up a field in a distance matrix * type table such as the expression or homology tables. */ { char *table = nextWord(¶meters); char *curGene = nextWord(¶meters); char *otherGene = nextWord(¶meters); char *valField = nextWord(¶meters); if (valField == NULL) errAbort("Not enough fields in type distance for %s", col->name); distanceTypeMethods(col, table, curGene, otherGene, valField); } /* ---------- Lookup floating point number column ------------- */ struct genePos *floatAdvFilter(struct column *col, struct sqlConnection *conn, struct genePos *list) /* Do advanced filter on float type. */ { char *minString = advFilterVal(col, "min"); char *maxString = advFilterVal(col, "max"); if (minString != NULL || maxString != NULL) { struct dyString *dy = newDyString(512); dyStringPrintf(dy, "select %s from %s where ", col->keyField, col->table); if (minString && maxString) dyStringPrintf(dy, "%s >= %s and %s <= %s", col->valField, minString, col->valField, maxString); else if (minString) dyStringPrintf(dy, "%s >= %s", col->valField, minString); else dyStringPrintf(dy, "%s <= %s", col->valField, maxString); list = advFilterFromQuery(conn, dy->string, list); dyStringFree(&dy); } return list; } void setupColumnFloat(struct column *col, char *parameters) /* Set up column that just looks up one floating point field * in a table keyed by the geneId. */ { setupColumnLookup(col, parameters); col->simpleSearch = NULL; col->cellPrint = cellSimplePrintNoLookupUrl; col->filterControls = minMaxAdvFilterControls; col->advFilter = floatAdvFilter; } #ifdef OLD void setupColumnFloat(struct column *col, char *parameters) /* Set up column that looks up one numerical field in a table * keyed by the geneId. */ { col->table = cloneString(nextWord(¶meters)); col->keyField = cloneString(nextWord(¶meters)); col->valField = cloneString(nextWord(¶meters)); if (col->valField == NULL) errAbort("Not enough fields in type float for %s", col->name); col->exists = simpleTableExists; col->cellVal = cellLookupVal; col->cellPrint = cellSimplePrintNoLookupUrl; col->filterControls = minMaxAdvFilterControls; col->advFilter = floatAdvFilter; } #endif /* OLD */ /* ---- Page/Form Making stuff ---- */ static void makeGenomeAssemblyControls() /* Query database to figure out which ones * support gene sorter. */ { /* Make up a list of genome that have a gene * sorter, and a list of assemblies that have a * gene sorter for the current genome. */ struct slRef *as, *asList = NULL; struct slRef *org, *orgList = NULL; struct dbDb *db, *dbList = hGetIndexedDatabases(); char *ourOrg = hGenome(database); struct hash *orgHash = newHash(8); for (db = dbList; db != NULL; db = db->next) { if (db->hgNearOk) { if (!hashLookup(orgHash, db->genome)) { hashAdd(orgHash, db->genome, db); refAdd(&orgList, db); } if (sameString(ourOrg, db->genome)) refAdd(&asList, db); } } slReverse(&asList); slReverse(&orgList); /* Make genome drop-down. */ hPrintf("genome "); hPrintf(""); /* Make assembly drop-down. */ hPrintf(" assembly "); hPrintf(""); /* Clean up time. */ slFreeList(&asList); slFreeList(&orgList); hashFree(&orgHash); dbDbFree(&dbList); } void controlPanelStart() /* Put up start of tables around a control panel. */ { hPrintf("
"); hPrintf("
"); hPrintf("
\n"); hPrintf("
"); } void controlPanelEnd() /* Put up end of tables around a control panel. */ { hPrintf("
"); hPrintf("
"); hPrintf("
"); hPrintf("
"); } static void mainControlPanel(struct genePos *gp, struct order *curOrd, struct order *ordList) /* Make control panel. */ { controlPanelStart(); makeGenomeAssemblyControls(); /* Do search box. */ { char *search = ""; if (gp != NULL) search = gp->name; hPrintf(" search "); cgiMakeTextVar(searchVarName, search, 25); } /* Do go button. */ { hPrintf(" "); printf("", "submit", "Go!"); } hPrintf("\n"); /* Do sort by drop-down */ { struct order *ord; hPrintf(""); hPrintf("sort by"); hPrintf(" "); hPrintf("\n"); } /* advFilter, configure buttons */ { cgiMakeButton(confVarName, "configure"); hPrintf(" "); if (gotAdvFilter()) cgiMakeButton(advFilterVarName, "filter (now on)"); else cgiMakeButton(advFilterVarName, "filter (now off)"); hPrintf(" "); } /* Do items to display drop-down */ { static char *menu[] = {"25", "50", "100", "200", "500", "1000", "all"}; int i = 0; hPrintf(" display "); hPrintf("\n"); } /* Make getDna, getText buttons */ { hPrintf(" output "); cgiMakeOptionalButton(getSeqPageVarName, "sequence", gp == NULL); hPrintf(" "); cgiMakeOptionalButton(getTextVarName, "text", gp == NULL); } controlPanelEnd(); } static void trimFarGenes(struct genePos **pList) /* Remove genes that are genePosTooFar or farther from list. */ { struct genePos *newList = NULL, *gp, *next; for (gp = *pList; gp != NULL; gp = next) { next = gp->next; if (gp->distance < genePosTooFar || sameString(gp->name, curGeneId->name)) { slAddHead(&newList, gp); } } slReverse(&newList); *pList = newList; } struct genePos *getOrderedList(struct order *ord, struct column *colList, struct sqlConnection *conn, int maxCount) /* Return sorted list of gene neighbors. */ { struct genePos *geneList = advFilterResults(colList, conn); struct hash *geneHash = newHash(16); struct genePos *gp; /* Make hash of all genes. */ for (gp = geneList; gp != NULL; gp = gp->next) { hashAdd(geneHash, gp->name, gp); } /* Calculate distances, trim unset distances, and sort. */ if (ord->calcDistances) ord->calcDistances(ord, conn, &geneList, geneHash, maxCount); if (!gotAdvFilter()) trimFarGenes(&geneList); slSort(&geneList, genePosCmpDistance); /* Trim list to max number. */ gp = slElementFromIx(geneList, maxCount-1); if (gp != NULL) gp->next = NULL; return geneList; } int columnCmpPriority(const void *va, const void *vb) /* Compare to sort columns based on priority. */ { const struct column *a = *((struct column **)va); const struct column *b = *((struct column **)vb); float dif = a->priority - b->priority; if (dif < 0) return -1; else if (dif > 0) return 1; else return 0; } void refinePriorities(struct hash *colHash) /* Consult colOrderVar if it exists to reorder priorities. */ { char *orig = cartOptionalString(cart, colOrderVar); if (orig != NULL) { char *dupe = cloneString(orig); char *s = dupe; char *name, *val; struct column *col; while ((name = nextWord(&s)) != NULL) { if ((val = nextWord(&s)) == NULL || !isdigit(val[0])) { warn("Bad priority list: %s", orig); cartRemove(cart, colOrderVar); break; } col = hashFindVal(colHash, name); if (col != NULL) col->priority = atof(val); } freez(&dupe); } } void refineVisibility(struct column *colList) /* Consult cart to set on/off visibility. */ { char varName[128], *val; struct column *col; for (col = colList; col != NULL; col = col->next) { safef(varName, sizeof(varName), "%s%s.vis", colConfigPrefix, col->name); val = cartOptionalString(cart, varName); if (val != NULL) col->on = sameString(val, "1"); } } char *mustFindInRaHash(char *fileName, struct hash *raHash, char *name) /* Look up in ra hash or die trying. */ { char *val = hashFindVal(raHash, name); if (val == NULL) errAbort("Missing required %s field in %s", name, fileName); return val; } void setupColumnType(struct column *col) /* Set up methods and column-specific variables based on * track type. */ { char *dupe = cloneString(col->type); char *s = dupe; char *type = nextWord(&s); columnDefaultMethods(col); if (type == NULL) warn("Missing type value for column %s", col->name); if (sameString(type, "num")) setupColumnNum(col, s); else if (sameString(type, "debug")) setupColumnDebug(col, s); else if (sameString(type, "lookup")) setupColumnLookup(col, s); else if (sameString(type, "association")) setupColumnAssociation(col, s); else if (sameString(type, "float")) setupColumnFloat(col, s); else if (sameString(type, "acc")) setupColumnAcc(col, s); else if (sameString(type, "distance")) setupColumnDistance(col, s); else if (sameString(type, "knownPos")) setupColumnKnownPos(col, s); else if (sameString(type, "knownDetails")) setupColumnKnownDetails(col, s); else if (sameString(type, "knownName")) setupColumnKnownName(col, s); else if (sameString(type, "expRatio")) setupColumnExpRatio(col, s); else if (sameString(type, "expMulti")) setupColumnExpMulti(col, s); else if (sameString(type, "expMax")) setupColumnExpMax(col, s); else if (sameString(type, "go")) setupColumnGo(col, s); else if (sameString(type, "pfam")) setupColumnPfam(col, s); else if (sameString(type, "flyBdgp")) setupColumnFlyBdgp(col, s); else if (sameString(type, "intronSize")) setupColumnIntronSize(col, s); else if (sameString(type, "xyz")) setupColumnXyz(col, s); else if (sameString(type, "custom")) setupColumnCustom(col, s); else errAbort("Unrecognized type %s for %s", col->type, col->name); freez(&dupe); } static char *rootDir = "hgNearData"; struct hash *readRa(char *rootName) /* Read in ra in root, root/org, and root/org/database. */ { return hgReadRa(genome, database, rootDir, rootName, NULL); } static void getGenomeSettings() /* Set up genome settings hash */ { struct hash *hash = readRa("genome.ra"); char *name; if (hash == NULL) errAbort("Can't find anything in genome.ra"); name = hashMustFindVal(hash, "name"); if (!sameString(name, "global")) errAbort("Can't find global ra record in genome.ra"); genomeSettings = hash; } char *genomeSetting(char *name) /* Return genome setting value. Aborts if setting not found. */ { return hashMustFindVal(genomeSettings, name); } char *genomeOptionalSetting(char *name) /* Return genome setting value. Returns NULL if not found. */ { return hashFindVal(genomeSettings, name); } char *protToGeneId(struct sqlConnection *conn, char *protId) /* Convert from protein to gene ID. */ { char *table = genomeSetting("geneTable"); char query[256]; safef(query, sizeof(query), "select name from %s where proteinId='%s'", table, protId); return sqlQuickString(conn, query); } void columnVarsFromSettings(struct column *col, char *fileName) /* Grab a bunch of variables from col->settings and * move them into col proper. */ { struct hash *settings = col->settings; char *selfLink; col->name = mustFindInRaHash(fileName, settings, "name"); spaceToUnderbar(col->name); col->shortLabel = mustFindInRaHash(fileName, settings, "shortLabel"); col->longLabel = mustFindInRaHash(fileName, settings, "longLabel"); col->priority = atof(mustFindInRaHash(fileName, settings, "priority")); col->on = col->defaultOn = sameString(mustFindInRaHash(fileName, settings, "visibility"), "on"); col->type = mustFindInRaHash(fileName, settings, "type"); col->itemUrl = hashFindVal(settings, "itemUrl"); col->itemUrlQuery = hashFindVal(settings, "itemUrlQuery"); col->useHgsid = columnSettingExists(col, "hgsid"); col->urlChromVar = hashFindVal(settings, "urlChromVar"); col->urlStartVar = hashFindVal(settings, "urlStartVar"); col->urlEndVar = hashFindVal(settings, "urlEndVar"); col->urlOtherGeneVar = hashFindVal(settings, "urlOtherGeneVar"); selfLink = hashFindVal(settings, "selfLink"); if (selfLink != NULL && selfLink[0] != '0') col->selfLink = TRUE; } static struct hash *hashColumns(struct column *colList) /* Return a hash of columns keyed by name. */ { struct column *col; struct hash *hash = hashNew(8); for (col = colList; col != NULL; col = col->next) { if (hashLookup(hash, col->name)) warn("duplicate %s in column list", col->name); hashAdd(hash, col->name, col); } return hash; } struct column *getColumns(struct sqlConnection *conn) /* Return list of columns for big table. */ { char *raName = "columnDb.ra"; struct column *col, *next, *customList, *colList = NULL; struct hash *raList = readRa(raName), *raHash = NULL; /* Create built-in columns. */ if (raList == NULL) errAbort("Couldn't find anything from %s", raName); for (raHash = raList; raHash != NULL; raHash = raHash->next) { AllocVar(col); col->settings = raHash; columnVarsFromSettings(col, raName); if (!hashFindVal(raHash, "hide")) { setupColumnType(col); if (col->exists(col, conn)) { slAddHead(&colList, col); } } } /* Create custom columns. */ customList = customColumnsRead(conn, genome, database); for (col = customList; col != NULL; col = next) { next = col->next; setupColumnType(col); if (col->exists(col, conn)) { slAddHead(&colList, col); } } /* Put columns in hash */ columnHash = hashColumns(colList); /* Tweak ordering and visibilities as per user settings. */ refinePriorities(columnHash); refineVisibility(colList); slSort(&colList, columnCmpPriority); return colList; } struct column *findNamedColumn(char *name) /* Return column of given name from list or NULL if none. */ { if (columnHash == NULL) internalErr(); return hashFindVal(columnHash, name); } int totalHtmlColumns(struct column *colList) /* Count up columns in big-table html. */ { int count = 0; struct column *col; for (col = colList; col != NULL; col = col->next) { if (col->on) count += col->tableColumns(col); } return count; } void bigTable(struct sqlConnection *conn, struct column *colList, struct genePos *geneList) /* Put up great big table. */ { struct column *col; struct genePos *gene; if (geneList == NULL) { if (gotAdvFilter()) { warn("No genes passed filter."); } return; } hPrintf("\n", totalHtmlColumns(colList)); /* Print label row. */ hPrintf(""); for (col = colList; col != NULL; col = col->next) { if (col->on) { col->labelPrint(col); } } hPrintf("\n"); /* Print other rows. */ hPrintf(""); for (gene = geneList; gene != NULL; gene = gene->next) { if (sameString(gene->name, curGeneId->name)) hPrintf(""); else hPrintf(""); for (col = colList; col != NULL; col = col->next) { if (col->on) { if (col->cellPrint == NULL) hPrintf(""); else col->cellPrint(col,gene,conn); } } hPrintf("\n"); if (ferror(stdout)) errAbort("Write error to stdout"); } hPrintf(""); hPrintf("
"); } void doGetText(struct sqlConnection *conn, struct column *colList, struct genePos *geneList) /* Put up great big table. */ { struct genePos *gene; struct column *col; boolean first = TRUE; makeTitle("Gene Sorter Text Output", NULL); if (geneList == NULL) { hPrintf("empty table"); return; } hPrintf("
");

/* Print labels. */
hPrintf("#");
for (col = colList; col != NULL; col = col->next)
    {
    if (col->on)
	{
	if (first)
	    first = FALSE;
	else
	    hPrintf("\t");
	hPrintf("%s", col->name);
	}
    }
hPrintf("\n");
for (gene = geneList; gene != NULL; gene = gene->next)
    {
    first = TRUE;
    for (col = colList; col != NULL; col = col->next)
	{
	if (col->on)
	    {
	    char *val = col->cellVal(col, gene, conn);
	    if (first)
	        first = FALSE;
	    else
		hPrintf("\t");
	    if (val == NULL)
		hPrintf("n/a");
	    else
		hPrintf("%s", val);
	    freez(&val);
	    }
	}
    hPrintf("\n");
    }
hPrintf("
"); } void doMainDisplay(struct sqlConnection *conn, struct order *ord, struct order *ordList, struct column *colList, struct genePos *geneList) /* Put up the main gene sorter display - a control panel followed by * a big table. */ { cartWebStart(cart, database, "UCSC %s Gene Sorter", genome); hPrintf("
\n"); cartSaveSession(cart); mainControlPanel(curGeneId, ord, ordList); if (geneList != NULL) bigTable(conn, colList,geneList); hPrintf("
\n"); hPrintf("
\n"); hPrintf("\n", genome); hPrintf("\n", database); hPrintf("\n", orderVarName, cartUsualString(cart, orderVarName, "")); hPrintf("\n", countVarName, cartUsualString(cart, countVarName, "")); cartSaveSession(cart); puts("
"); } struct order *curOrder(struct order *ordList) /* Get ordering currently selected by user, or default * (first in list) if none selected. */ { char *selName; struct order *ord; if (ordList == NULL) errAbort("No orderings available"); selName = cartUsualString(cart, orderVarName, ordList->name); for (ord = ordList; ord != NULL; ord = ord->next) { if (sameString(ord->name, selName)) return ord; } return ordList; } char *lookupProtein(struct sqlConnection *conn, char *mrnaName) /* Given mrna name look up protein. FreeMem result when done. */ { char query[256]; char buf[64]; if (kgVersion == KG_III) { safef(query, sizeof(query), "select spDisplayID from kgXref where kgId='%s'", mrnaName); } else { safef(query, sizeof(query), "select protein from %s where transcript='%s'", genomeSetting("canonicalTable"), mrnaName); } if (!sqlQuickQuery(conn, query, buf, sizeof(buf))) return NULL; return cloneString(buf); } void displayData(struct sqlConnection *conn, struct column *colList, struct genePos *gp) /* Display data in neighborhood of gene. */ { struct genePos *geneList = NULL; struct order *ordList = orderGetAll(conn); struct order *ord = curOrder(ordList); if (gp != NULL && gp->protein == NULL) gp->protein = lookupProtein(conn, gp->name); curGeneId = gp; if (cartVarExists(cart, getTextVarName)) { if (gp) geneList = getOrderedList(ord, colList, conn, BIGNUM); doGetText(conn, colList, geneList); } else if (cartVarExists(cart, getSeqVarName)) { if (gp) geneList = getOrderedList(ord, colList, conn, BIGNUM); doGetSeq(conn, colList, geneList, cartString(cart, getSeqHowVarName)); } else if (cartVarExists(cart, getGenomicSeqVarName)) { if (gp) geneList = getOrderedList(ord, colList, conn, BIGNUM); doGetGenomicSeq(conn, colList, geneList); } else { if (gp) geneList = getOrderedList(ord, colList, conn, displayCount); doMainDisplay(conn, ord, ordList, colList, geneList); } } static struct genePos *curGenePos() /* Return current gene pos from cart variables. */ { struct genePos *gp; AllocVar(gp); gp->name = cloneString(cartString(cart, idVarName)); /* Update cart's searchVarName to idVarName so that subsequent clicks will * have the right value in orgForm's searchVarName. */ cartSetString(cart, searchVarName, gp->name); if (cartVarExists(cart, idPosVarName)) { hgParseChromRange(database, cartString(cart, idPosVarName), &gp->chrom, &gp->start, &gp->end); gp->chrom = cloneString(gp->chrom); } return gp; } void doFixedId(struct sqlConnection *conn, struct column *colList) /* Put up the main page based on id/idPos. */ { displayData(conn, colList, curGenePos()); } static char *colHtmlFileName(struct column *col) /* Return html file associated with column. You can * freeMem this when done. */ { char name[PATH_LEN]; char *org = hgDirForOrg(genome); safef(name, sizeof(name), "%s/%s/%s/%s.html", rootDir, org, database, col->name); if (!fileExists(name)) { safef(name, sizeof(name), "%s/%s/%s.html", rootDir, org, col->name); if (!fileExists(name)) safef(name, sizeof(name), "%s/%s.html", rootDir, col->name); } freez(&org); return cloneString(name); } void doColInfo(struct sqlConnection *conn, struct column *colList, char *colName) /* Put up info page on column. */ { struct column *col = findNamedColumn(colName); char buf[1024]; char *htmlFileName; if (col == NULL) errAbort("Can't find column '%s'", colName); safef(buf, sizeof(buf), "Column %s - %s", col->shortLabel, col->longLabel); makeTitle(buf, NULL); htmlFileName = colHtmlFileName(col); if (fileExists(htmlFileName)) { char *html; readInGulp(htmlFileName, &html, NULL); hVarSubstInVar(colName, NULL,database, &html); hPrintf("%s", html); freez(&html); } else { hPrintf("No additional info available on %s column", col->shortLabel); } freeMem(htmlFileName); } static char *defaultHgNearDb(char *genome) /* Return default database for hgNear for given * genome (or NULL for default genome.) * You can freeMem the returned value when done. */ { char *dbName = NULL; struct dbDb *db = NULL, *dbList = NULL; if (genome != NULL) { dbName = hDefaultDbForGenome(genome); if (dbName != NULL && hgNearOk(dbName)) return dbName; freez(&dbName); // Find first db with given genome and hgNearOk in ordered list: dbList = hGetIndexedDatabases(); for (db = dbList; db != NULL; db = db->next) { if (sameString(genome, db->genome) && db->hgNearOk) { dbName = cloneString(db->name); dbDbFree(&dbList); return dbName; } } } freez(&dbName); dbName = hDefaultDb(); if (dbName != NULL && hgNearOk(dbName)) return dbName; freez(&dbName); // Find first db with hgNearOk in ordered list: if (dbList == NULL) dbList = hGetIndexedDatabases(); for (db = dbList; db != NULL; db = db->next) { if (db->hgNearOk) { dbName = cloneString(db->name); break; } } dbDbFree(&dbList); return dbName; } static void makeSureDbHasHgNear() /* Check that current database supports hgNear. * If not try to find one that does. */ { if (hgNearOk(database)) return; else { database = defaultHgNearDb(genome); if (database == NULL) errAbort("No databases are supporting hgNear."); genome = hGenome(database); cartSetString(cart, dbVarName, database); cartSetString(cart, orgVarName, genome); } } void doMiddle(struct cart *theCart) /* Write the middle parts of the HTML page. * This routine sets up some globals and then * dispatches to the appropriate page-maker. */ { char *var = NULL; struct sqlConnection *conn; struct column *colList, *col; cart = theCart; getDbAndGenome(cart, &database, &genome, oldVars); makeSureDbHasHgNear(); getGenomeSettings(); conn = hAllocConn(database); /* if kgProtMap2 table exists, this means we are doing KG III */ if (hTableExists(database, "kgProtMap2")) kgVersion = KG_III; /* Get groupOn. Revert to default if no advanced filter. */ groupOn = cartUsualString(cart, groupVarName, "expression"); displayCountString = cartUsualString(cart, countVarName, "50"); if (sameString(displayCountString, "all")) displayCount = BIGNUM; else displayCount = atoi(displayCountString); colList = getColumns(conn); /* Main dispatch logic on near.do.XXXX */ if (cartVarExists(cart, confVarName)) doConfigure(conn, colList, NULL); else if (cartVarExists(cart, colInfoVarName)) doColInfo(conn, colList, cartString(cart, colInfoVarName)); else if ((var = cartFindFirstLike(cart, "near.do.up.*")) != NULL) { doConfigure(conn, colList, var); } else if ((var = cartFindFirstLike(cart, "near.do.down.*")) != NULL) { doConfigure(conn, colList, var); } else if (cartVarExists(cart, defaultConfName)) doDefaultConfigure(conn, colList); else if (cartVarExists(cart, hideAllConfName)) doConfigHideAll(conn, colList); else if (cartVarExists(cart, showAllConfName)) doConfigShowAll(conn, colList); else if (cartVarExists(cart, saveCurrentConfName)) doNameCurrentColumns(); else if (cartVarExists(cart, savedCurrentConfName)) doSaveCurrentColumns(conn, colList); else if (cartVarExists(cart, useSavedConfName)) doConfigUseSaved(conn, colList); else if (cartVarExists(cart, filSaveCurrentVarName)) doNameCurrentFilters(); else if (cartVarExists(cart, filSavedCurrentVarName)) doSaveCurrentFilters(conn, colList); else if (cartVarExists(cart, filUseSavedVarName)) doUseSavedFilters(conn, colList); else if (cartVarExists(cart, advFilterVarName)) doAdvFilter(conn, colList); else if (cartVarExists(cart, advFilterClearVarName)) doAdvFilterClear(conn, colList); else if (cartVarExists(cart, advFilterListVarName)) doAdvFilterList(conn, colList); else if (cartVarExists(cart, getSeqPageVarName)) doGetSeqPage(conn, colList); else if (cartVarExists(cart, idVarName)) doFixedId(conn, colList); else if ((col = advFilterKeyPastePressed(colList)) != NULL) doAdvFilterKeyPaste(conn, colList, col); else if ((col = advFilterKeyPastedPressed(colList)) != NULL) doAdvFilterKeyPasted(conn, colList, col); else if ((col = advFilterKeyUploadPressed(colList)) != NULL) doAdvFilterKeyUpload(conn, colList, col); else if ((col = advFilterKeyClearPressed(colList)) != NULL) doAdvFilterKeyClear(conn, colList, col); else if (cartVarExists(cart, customPageDoName)) doCustomPage(conn, colList); else if (cartVarExists(cart, customSubmitDoName)) doCustomSubmit(conn, colList); else if (cartVarExists(cart, customClearDoName)) doCustomClear(conn, colList); else if (cartVarExists(cart, customPasteDoName)) doCustomPaste(conn, colList); else if (cartVarExists(cart, customUploadDoName)) doCustomUpload(conn, colList); else if (cartVarExists(cart, customFromUrlDoName)) doCustomFromUrl(conn, colList); else if (cartVarExists(cart, orderInfoDoName)) doOrderInfo(conn); else if (cartVarExists(cart, affineAliVarName)) doAffineAlignment(conn); else if (cartNonemptyString(cart, searchVarName)) doSearch(conn, colList); else if (gotAdvFilter()) displayData(conn, colList, knownPosFirst(conn)); else doExamples(conn, colList); hFreeConn(&conn); cartRemovePrefix(cart, "near.do."); cartWebEnd(); } void usage() /* Explain usage and exit. */ { errAbort( "hgNear - gene sorter - a cgi script\n" "usage:\n" " hgNear\n" ); } int main(int argc, char *argv[]) /* Process command line. */ { long enteredMainTime = clock1000(); // pushCarefulMemHandler(100000000); cgiSpoof(&argc, argv); htmlSetStyle(htmlStyleUndecoratedLink); htmlSetBgColor(HG_CL_OUTSIDE); oldVars = hashNew(10); cartEmptyShell(doMiddle, hUserCookie(), excludeVars, oldVars); cgiExitTime("hgNear", enteredMainTime); return 0; }