static int findTileSize(char *line) /* Parse through line/val pairs looking for tileSize. */ { char *var, *val; int tileSize = 4; for (;;) { var = nextWord(&line); if (var == NULL) break; val = nextWord(&line); if (val == NULL) { internalErr(); break; } if (sameString("tileSize", var)) { tileSize = atoi(val); if (tileSize <= 0) internalErr(); } } return tileSize; }
static void jrRowExpand(struct joinedTables *joined, struct joinedRow *jr, char **row, int fieldOffset, int fieldCount, int keyOffset, int keyCount) /* Add some more to row. */ { int i; struct slName **keys = jr->keys + keyOffset; struct slName **fields = jr->fields + fieldOffset; struct lm *lm = joined->lm; struct slName *name; if (fieldCount + fieldOffset > joined->fieldCount) internalErr(); if (keyCount + keyOffset > joined->keyCount) internalErr(); for (i=0; i<fieldCount; ++i) { name = lmSlName(lm, row[i]); slAddTail(&fields[i], name); } row += fieldCount; for (i=0; i<keyCount; ++i) { name = lmSlName(lm, row[i]); slAddHead(&keys[i], name); } }
void checkInputOpenFiles(struct inInfo *array, int count) /* Make sure all of the input is there and of right format before going forward. Since * this is going to take a while we want to fail fast. */ { int i; for (i=0; i<count; ++i) { struct inInfo *in = &array[i]; switch (in->type) { case itBigWig: { /* Just open and close, it will abort if any problem. */ in->bbi = bigWigFileOpen(in->fileName); break; } case itPromoterBed: case itUnstrandedBed: case itBlockedBed: { struct lineFile *lf = in->lf = lineFileOpen(in->fileName, TRUE); char *line; lineFileNeedNext(lf, &line, NULL); char *dupe = cloneString(line); char *row[256]; int wordCount = chopLine(dupe, row); struct bed *bed = NULL; switch (in->type) { case itPromoterBed: lineFileExpectAtLeast(lf, 6, wordCount); bed = bedLoadN(row, 6); char strand = bed->strand[0]; if (strand != '+' && strand != '-') errAbort("%s must be stranded, got %s in that field", lf->fileName, row[6]); break; case itUnstrandedBed: lineFileExpectAtLeast(lf, 4, wordCount); bed = bedLoadN(row, 4); break; case itBlockedBed: lineFileExpectAtLeast(lf, 4, wordCount); bed = bedLoadN(row, 12); break; default: internalErr(); break; } bedFree(&bed); freez(&dupe); lineFileReuse(lf); break; } default: internalErr(); break; } } }
struct slName *bigBedListExtraIndexes(struct bbiFile *bbi) /* Return list of names of extra indexes beyond primary chrom:start-end one" */ { struct udcFile *udc = bbi->udc; boolean isSwapped = bbi->isSwapped; /* See if we have any extra indexes, and if so seek to there. */ bits64 offset = bbi->extraIndexListOffset; if (offset == 0) return NULL; udcSeek(udc, offset); /* Construct list of field that are being indexed. List is list of * field numbers within asObj. */ int i; struct slInt *intList = NULL, *intEl; for (i=0; i<bbi->extraIndexCount; ++i) { bits16 type,fieldCount; type = udcReadBits16(udc, isSwapped); fieldCount = udcReadBits16(udc, isSwapped); udcSeekCur(udc, sizeof(bits64)); // skip over fileOffset udcSeekCur(udc, 4); // skip over reserved bits if (fieldCount == 1) { bits16 fieldId = udcReadBits16(udc, isSwapped); udcSeekCur(udc, 2); // skip over reserved bits intEl = slIntNew(fieldId); slAddHead(&intList, intEl); } else { warn("Not yet understanding indexes on multiple fields at once."); internalErr(); } } /* Now have to make an asObject to find out name that corresponds to this field. */ struct asObject *as = bigBedAsOrDefault(bbi); /* Make list of field names out of list of field numbers */ struct slName *nameList = NULL; for (intEl = intList; intEl != NULL; intEl = intEl->next) { struct asColumn *col = slElementFromIx(as->columnList, intEl->val); if (col == NULL) { warn("Inconsistent bigBed file %s", bbi->fileName); internalErr(); } slNameAddHead(&nameList, col->name); } asObjectFree(&as); return nameList; }
struct bptFile *bigBedOpenExtraIndex(struct bbiFile *bbi, char *fieldName, int *retFieldIx) /* Return index associated with fieldName. Aborts if no such index. Optionally return * index in a row of this field. */ { struct udcFile *udc = bbi->udc; boolean isSwapped = bbi->isSwapped; struct asObject *as = bigBedAsOrDefault(bbi); struct asColumn *col = asColumnFind(as, fieldName); if (col == NULL) errAbort("No field %s in %s", fieldName, bbi->fileName); int colIx = slIxFromElement(as->columnList, col); if (retFieldIx != NULL) *retFieldIx = colIx; asObjectFree(&as); /* See if we have any extra indexes, and if so seek to there. */ bits64 offset = bbi->extraIndexListOffset; if (offset == 0) errAbort("%s has no indexes", bbi->fileName); udcSeek(udc, offset); /* Go through each extra index and see if it's a match */ int i; for (i=0; i<bbi->extraIndexCount; ++i) { bits16 type = udcReadBits16(udc, isSwapped); bits16 fieldCount = udcReadBits16(udc, isSwapped); bits64 fileOffset = udcReadBits64(udc, isSwapped); udcSeekCur(udc, 4); // skip over reserved bits if (type != 0) { warn("Don't understand type %d", type); internalErr(); } if (fieldCount == 1) { bits16 fieldId = udcReadBits16(udc, isSwapped); udcSeekCur(udc, 2); // skip over reserved bits if (fieldId == colIx) { udcSeek(udc, fileOffset); struct bptFile *bpt = bptFileAttach(bbi->fileName, udc); return bpt; } } else { warn("Not yet understanding indexes on multiple fields at once."); internalErr(); } } errAbort("%s is not indexed in %s", fieldName, bbi->fileName); return NULL; }
void recordIntoHistory(struct sqlConnection *conn, unsigned id, char *table, boolean success) /* Record success/failure into uploadAttempts and historyBits fields of table. */ { /* Get historyBits and fold status into it. */ char quickResult[32]; char query[256]; sqlSafef(query, sizeof(query), "select historyBits from %s where id=%u", table, id); if (sqlQuickQuery(conn, query, quickResult, sizeof(quickResult)) == NULL) internalErr(); char *lastTimeField; char *openResultField; long long historyBits = sqlLongLong(quickResult); historyBits <<= 1; if (success) { historyBits |= 1; lastTimeField = "lastOkTime"; openResultField = "openSuccesses"; } else { lastTimeField = "lastNotOkTime"; openResultField = "openFails"; } sqlSafef(query, sizeof(query), "update %s set historyBits=%lld, %s=%s+1, %s=%lld " "where id=%lld", table, historyBits, openResultField, openResultField, lastTimeField, edwNow(), (long long)id); sqlUpdate(conn, query); }
static struct rqlParse *rqlParseCoerce(struct rqlParse *p, enum rqlType type) /* If p is not of correct type, wrap type conversion node around it. */ { if (p->type == type) return p; else { struct rqlParse *cast; AllocVar(cast); cast->children = p; cast->type = type; switch (type) { case rqlTypeBoolean: cast->op = booleanCastOp(p->type); break; case rqlTypeInt: cast->op = intCastOp(p->type); break; case rqlTypeDouble: cast->op = doubleCastOp(p->type); break; default: internalErr(); break; } return cast; } }
struct bbiSummary *bwgReduceSectionList(struct bwgSection *sectionList, struct bbiChromInfo *chromInfoArray, int reduction) /* Return summary of section list reduced by given amount. */ { struct bbiSummary *outList = NULL; struct bwgSection *section = NULL; /* Loop through input section list reducing into outList. */ for (section = sectionList; section != NULL; section = section->next) { bits32 chromSize = chromInfoArray[section->chromId].size; switch (section->type) { case bwgTypeBedGraph: bwgReduceBedGraph(section, chromSize, reduction, &outList); break; case bwgTypeVariableStep: bwgReduceVariableStep(section, chromSize, reduction, &outList); break; case bwgTypeFixedStep: bwgReduceFixedStep(section, chromSize, reduction, &outList); break; default: internalErr(); return 0; } } slReverse(&outList); return outList; }
static struct rqlEval rqlEvalLt(struct rqlParse *p, void *record, RqlEvalLookup lookup, struct lm *lm) /* Return true if r < l . */ { struct rqlParse *lp = p->children; struct rqlParse *rp = lp->next; struct rqlEval lv = rqlLocalEval(lp, record, lookup, lm); struct rqlEval rv = rqlLocalEval(rp, record, lookup, lm); struct rqlEval res; res.type = rqlTypeBoolean; switch (lv.type) { case rqlTypeBoolean: res.val.b = (lv.val.b < rv.val.b); break; case rqlTypeString: res.val.b = strcmp(lv.val.s, rv.val.s) < 0; break; case rqlTypeInt: res.val.b = (lv.val.i < rv.val.i); break; case rqlTypeDouble: res.val.b = (lv.val.x < rv.val.x); break; default: internalErr(); res.val.b = FALSE; break; } return res; }
void bptFileBulkIndexToOpenFile(void *itemArray, int itemSize, bits64 itemCount, bits32 blockSize, void (*fetchKey)(const void *va, char *keyBuf), bits32 keySize, void* (*fetchVal)(const void *va), bits32 valSize, FILE *f) /* Create a b+ tree index from a sorted array, writing output starting at current position * of an already open file. See bptFileCreate for explanation of parameters. */ { bits32 magic = bptSig; bits32 reserved = 0; writeOne(f, magic); writeOne(f, blockSize); writeOne(f, keySize); writeOne(f, valSize); writeOne(f, itemCount); writeOne(f, reserved); writeOne(f, reserved); bits64 indexOffset = ftell(f); /* Write non-leaf nodes. */ int levels = bptCountLevels(blockSize, itemCount); int i; for (i=levels-1; i > 0; --i) { bits32 endLevelOffset = writeIndexLevel(blockSize, itemArray, itemSize, itemCount, indexOffset, i, fetchKey, keySize, valSize, f); indexOffset = ftell(f); if (endLevelOffset != indexOffset) internalErr(); } /* Write leaf nodes */ writeLeafLevel(blockSize, itemArray, itemSize, itemCount, fetchKey, keySize, fetchVal, valSize, f); }
static double getSignalAt(char *table, struct bed *cluster) /* Get (average) signal from table entries that overlap cluster */ { struct sqlConnection *conn = hAllocConn(database); int count = 0; double sum = 0; if (sqlTableExists(conn, table)) // Table might be withdrawn from data thrash { int rowOffset; struct sqlResult *sr = hRangeQuery(conn, table, cluster->chrom, cluster->chromStart, cluster->chromEnd, NULL, &rowOffset); int signalCol = sqlFieldColumn(sr, "signalValue"); if (signalCol < 0) internalErr(); char **row; while ((row = sqlNextRow(sr)) != NULL) { count += 1; sum += sqlDouble(row[signalCol]); } sqlFreeResult(&sr); } hFreeConn(&conn); if (count > 0) return sum/count; else return 0; }
static void castFromDouble(struct pfCompile *pfc, struct isx *isx, struct dlNode *nextNode, struct pentCoder *coder) /* Create code for cast from float to something else. */ { switch (isx->dest->valType) { case ivBit: castFloatOrDoubleToBit(pfc, isx, nextNode, coder); break; case ivByte: case ivShort: case ivInt: castByOneViaType(pfc, isx, nextNode, coder, "cvtsd2si", ivInt); break; case ivLong: castFloatOrDoubleToLong(pfc, isx, nextNode, coder, 8, "fldl"); break; case ivFloat: castByOneInstruction(pfc, isx, nextNode, coder, "cvtsd2ss"); break; default: internalErr(); break; } }
void pentCast(struct pfCompile *pfc, struct isx *isx, struct dlNode *nextNode, struct pentCoder *coder) /* Create code for a cast instruction */ { switch (isx->left->valType) { case ivBit: case ivByte: castFromBitOrByte(pfc, isx, nextNode, coder); break; case ivShort: castFromShort(pfc, isx, nextNode, coder); break; case ivInt: castFromInt(pfc, isx, nextNode, coder); break; case ivLong: castFromLong(pfc, isx, nextNode, coder); break; case ivFloat: castFromFloat(pfc, isx, nextNode, coder); break; case ivDouble: castFromDouble(pfc, isx, nextNode, coder); break; default: internalErr(); } }
static void castFromLong(struct pfCompile *pfc, struct isx *isx, struct dlNode *nextNode, struct pentCoder *coder) /* Create code for cast from long to something else. */ { switch (isx->dest->valType) { case ivBit: castLongToBit(pfc, isx, nextNode, coder); break; case ivByte: case ivShort: case ivInt: castLongToByteShortInt(pfc, isx, nextNode, coder); break; case ivFloat: castLongToFloatOrDouble(pfc, isx, nextNode, coder, 4, "fstps", "movss"); break; case ivDouble: castLongToFloatOrDouble(pfc, isx, nextNode, coder, 8, "fstpl", "movsd"); break; default: internalErr(); break; } }
static void castFromInt(struct pfCompile *pfc, struct isx *isx, struct dlNode *nextNode, struct pentCoder *coder) /* Create code for cast from int to something else. */ { switch (isx->dest->valType) { case ivBit: castIntToBit(pfc, isx, nextNode, coder); break; case ivByte: case ivShort: castViaMov(pfc, isx, nextNode, coder); break; case ivLong: castByOneInstruction(pfc, isx, nextNode, coder, "movd"); break; case ivFloat: castByOneInstruction(pfc, isx, nextNode, coder, "cvtsi2ss"); break; case ivDouble: castByOneInstruction(pfc, isx, nextNode, coder, "cvtsi2sd"); break; default: internalErr(); break; } }
static char *ccFreezeDbConversion(char *database, char *freeze, char *org) /* Find freeze given database or vice versa. Pass in NULL * for parameter that is unknown and it will be returned * as a result. This result can be freeMem'd when done. */ { struct sqlConnection *conn = hConnectCentral(); struct sqlResult *sr; char **row; char *ret = NULL; struct dyString *dy = newDyString(128); if (database != NULL) dyStringPrintf(dy, "select description from dbDb where name = '%s' and (genome like '%s' or genome like 'Zoo')", database, org); else if (freeze != NULL) dyStringPrintf(dy, "select name from dbDb where description = '%s' and (genome like '%s' or genome like 'Zoo')", freeze, org); else internalErr(); sr = sqlGetResult(conn, dy->string); if ((row = sqlNextRow(sr)) != NULL) ret = cloneString(row[0]); sqlFreeResult(&sr); hDisconnectCentral(&conn); freeDyString(&dy); return ret; }
struct column *findNamedColumn(char *name) /* Return column of given name from list or NULL if none. */ { if (columnHash == NULL) internalErr(); return hashFindVal(columnHash, name); }
static struct rqlEval rqlEvalEq(struct rqlParse *p, void *record, RqlEvalLookup lookup, struct lm *lm) /* Return true if two children are equal regardless of children type * (which are just gauranteed to be the same). */ { struct rqlParse *lp = p->children; struct rqlParse *rp = lp->next; struct rqlEval lv = rqlLocalEval(lp, record, lookup, lm); struct rqlEval rv = rqlLocalEval(rp, record, lookup, lm); struct rqlEval res; res.type = rqlTypeBoolean; assert(lv.type == rv.type); switch (lv.type) { case rqlTypeBoolean: res.val.b = (lv.val.b == rv.val.b); break; case rqlTypeString: res.val.b = sameString(lv.val.s, rv.val.s); break; case rqlTypeInt: res.val.b = (lv.val.i == rv.val.i); break; case rqlTypeDouble: res.val.b = (lv.val.x == rv.val.x); break; default: internalErr(); res.val.b = FALSE; break; } return res; }
void doIntersectPage(struct sqlConnection *conn) /* Respond to intersect create/edit button */ { if (ArraySize(curVars) != ArraySize(nextVars)) internalErr(); copyCartVars(cart, curVars, nextVars, ArraySize(curVars)); doIntersectMore(conn); }
void doSubtrackMergePage(struct sqlConnection *conn) /* Respond to subtrack merge create/edit button */ { if (ArraySize(curVars) != ArraySize(nextVars)) internalErr(); copyCartVars(cart, curVars, nextVars, ArraySize(curVars)); doSubtrackMergeMore(conn); }
int bwgAverageResolution(struct bwgSection *sectionList) /* Return the average resolution seen in sectionList. */ { if (sectionList == NULL) return 1; bits64 totalRes = 0; bits32 sectionCount = 0; struct bwgSection *section; int i; for (section = sectionList; section != NULL; section = section->next) { int sectionRes = 0; switch (section->type) { case bwgTypeBedGraph: { struct bwgBedGraphItem *item; sectionRes = BIGNUM; for (item = section->items.bedGraphList; item != NULL; item = item->next) { int size = item->end - item->start; if (sectionRes > size) sectionRes = size; } break; } case bwgTypeVariableStep: { struct bwgVariableStepPacked *items = section->items.variableStepPacked, *prev; bits32 smallestGap = BIGNUM; for (i=1; i<section->itemCount; ++i) { prev = items; items += 1; bits32 gap = items->start - prev->start; if (smallestGap > gap) smallestGap = gap; } if (smallestGap != BIGNUM) sectionRes = smallestGap; else sectionRes = section->itemSpan; break; } case bwgTypeFixedStep: { sectionRes = section->itemStep; break; } default: internalErr(); break; } totalRes += sectionRes; ++sectionCount; } return (totalRes + sectionCount/2)/sectionCount; }
void printCladeListHtml(char *genome, char *onChangeText) /* Make an HTML select input listing the clades. */ { char **row = NULL; char *clades[128]; char *labels[128]; char *defaultClade = hClade(genome); char *defaultLabel = NULL; int numClades = 0; struct sqlConnection *conn = hConnectCentral(); // after hClade since it access hgcentral too // get only the clades that have actual active genomes char query[4096]; safef(query, sizeof query, "NOSQLINJ SELECT DISTINCT(c.name), c.label FROM %s c, %s g, %s d WHERE c.name=g.clade AND d.organism=g.genome AND d.active=1 ORDER BY c.priority", cladeTable(),genomeCladeTable(), dbDbTable()); struct sqlResult *sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { clades[numClades] = cloneString(row[0]); labels[numClades] = cloneString(row[1]); if (sameWord(defaultClade, clades[numClades])) defaultLabel = clades[numClades]; numClades++; if (numClades >= ArraySize(clades)) internalErr(); } sqlFreeResult(&sr); hDisconnectCentral(&conn); struct slPair *names = trackHubGetCladeLabels(); for(; names; names = names->next) { clades[numClades] = names->name; labels[numClades] = names->val; if (sameWord(defaultClade, clades[numClades])) defaultLabel = clades[numClades]; numClades++; if (numClades >= ArraySize(clades)) internalErr(); } cgiMakeDropListFull(cladeCgiName, labels, clades, numClades, defaultLabel, onChangeText); }
int minSubs(int subCounts[3]) /* Return minimum number of substitutions. */ { int i; for (i=0; i<3; ++i) if (subCounts[i]) return i; internalErr(); return -1; }
char *gfTypeName(enum gfType type) /* Return string representing type. */ { if (type == gftDna) return "DNA"; if (type == gftRna) return "RNA"; if (type == gftProt) return "protein"; if (type == gftDnaX) return "DNAX"; if (type == gftRnaX) return "RNAX"; internalErr(); return NULL; }
void bbiAddToSummary(bits32 chromId, bits32 chromSize, bits32 start, bits32 end, bits32 validCount, double minVal, double maxVal, double sumData, double sumSquares, int reduction, struct bbiSummary **pOutList) /* Add data range to summary - putting it onto top of list if possible, otherwise * expanding list. */ { struct bbiSummary *sum = *pOutList; if (end > chromSize) // Avoid pathological clipping situation on bad input end = chromSize; while (start < end) { /* See if need to allocate a new summary. */ if (sum == NULL || sum->chromId != chromId || sum->end <= start) { struct bbiSummary *newSum; AllocVar(newSum); newSum->chromId = chromId; if (sum == NULL || sum->chromId != chromId || sum->end + reduction <= start) newSum->start = start; else newSum->start = sum->end; newSum->end = newSum->start + reduction; if (newSum->end > chromSize) newSum->end = chromSize; newSum->minVal = minVal; newSum->maxVal = maxVal; sum = newSum; slAddHead(pOutList, sum); } /* Figure out amount of overlap between current summary and item */ int overlap = rangeIntersection(start, end, sum->start, sum->end); if (overlap <= 0) { warn("%u %u doesn't intersect %u %u, chromId %u chromSize %u", start, end, sum->start, sum->end, chromId, chromSize); internalErr(); } int itemSize = end - start; double overlapFactor = (double)overlap/itemSize; /* Fold overlapping bits into output. */ sum->validCount += overlapFactor * validCount; if (sum->minVal > minVal) sum->minVal = minVal; if (sum->maxVal < maxVal) sum->maxVal = maxVal; sum->sumData += overlapFactor * sumData; sum->sumSquares += overlapFactor * sumSquares; /* Advance over overlapping bits. */ start += overlap; } }
void printAllAssemblyListHtmlParm(char *db, struct dbDb *dbList, char *dbCgi, bool allowInactive, char *javascript) /* Prints to stdout the HTML to render a dropdown list containing the list * of assemblies for the current genome to choose from. By default, * this includes only active assemblies with a database (with the * exception of the default assembly, which will be included even * if it isn't active). * param db - The default assembly (the database name) to choose as selected. * If NULL, no default selection. * param allowInactive - if set, print all assemblies for this genome, * even if they're inactive or have no database */ { char *assemblyList[128]; char *values[128]; int numAssemblies = 0; struct dbDb *cur = NULL; char *genome = hGenomeOrArchive(db); char *selAssembly = NULL; if (genome == NULL) #ifdef LOWELAB genome = "Pyrococcus furiosus"; #else genome = "Human"; #endif for (cur = dbList; cur != NULL; cur = cur->next) { /* Only for this genome */ if (!sameWord(genome, cur->genome)) continue; /* Save a pointer to the current assembly */ if (sameWord(db, cur->name)) selAssembly = cur->name; if (allowInactive || ((cur->active || sameWord(cur->name, db)) && (trackHubDatabase(db) || sqlDatabaseExists(cur->name)))) { assemblyList[numAssemblies] = cur->description; values[numAssemblies] = cur->name; numAssemblies++; if (numAssemblies >= ArraySize(assemblyList)) internalErr(); } } cgiMakeDropListFull(dbCgi, assemblyList, values, numAssemblies, selAssembly, javascript); }
boolean bbiSummaryArray(struct bbiFile *bbi, char *chrom, bits32 start, bits32 end, BbiFetchIntervals fetchIntervals, enum bbiSummaryType summaryType, int summarySize, double *summaryValues) /* Fill in summaryValues with data from indicated chromosome range in bigWig file. * Be sure to initialize summaryValues to a default value, which will not be touched * for regions without data in file. (Generally you want the default value to either * be 0.0 or nan("") depending on the application.) Returns FALSE if no data * at that position. */ { struct bbiSummaryElement *elements; AllocArray(elements, summarySize); boolean ret = bbiSummaryArrayExtended(bbi, chrom, start, end, fetchIntervals, summarySize, elements); if (ret) { int i; double covFactor = (double)summarySize/(end - start); for (i=0; i<summarySize; ++i) { struct bbiSummaryElement *el = &elements[i]; if (el->validCount > 0) { double val; switch (summaryType) { case bbiSumMean: val = el->sumData/el->validCount; break; case bbiSumMax: val = el->maxVal; break; case bbiSumMin: val = el->minVal; break; case bbiSumCoverage: val = covFactor*el->validCount; break; case bbiSumStandardDeviation: val = calcStdFromSums(el->sumData, el->sumSquares, el->validCount); break; default: internalErr(); val = 0.0; break; } summaryValues[i] = val; } } } freeMem(elements); return ret; }
struct trans3 *trans3Find(struct hash *t3Hash, char *name, int start, int end) /* Find trans3 in hash which corresponds to sequence of given name and includes * bases between start and end. */ { struct trans3 *t3; for (t3 = hashFindVal(t3Hash, name); t3 != NULL; t3 = t3->next) { if (t3->start <= start && t3->end >= end) return t3; } internalErr(); return NULL; }
char *clumpTargetName(struct gfClump *clump) /* Return target name of clump - whether it is in memory or on disk. */ { struct gfSeqSource *target = clump->target; char *name; if (target->seq != NULL) name = target->seq->name; else name = target->fileName; if (name == NULL) internalErr(); return name; }
void doAdvFilterListCol(struct sqlConnection *conn, struct column *colList, char *colName) /* List a column for genes matching advanced filter. */ { struct genePos *gp, *list = NULL, *newList = NULL, *gpNext = NULL; struct column *col = findNamedColumn(colName); makeTitle("Current Filters", NULL); if (col == NULL) { warn("No name column"); internalErr(); } hPrintf("<TT><PRE>"); if (gotAdvFilter()) { list = advFilterResults(colList, conn); } else { hPrintf("#No filters activated. List contains all genes.\n"); list = knownPosAll(conn); } /* Now lookup names and sort. */ for (gp = list; gp != NULL; gp = gpNext) { char *oldName = gp->name; gp->name = col->cellVal(col, gp, conn); gpNext = gp->next; if (gp->name == NULL) { warn("Unable to find cellVal for %s -- tables out of sync?", oldName); } else { slAddHead(&newList,gp); } } list = newList; slSort(&list, genePosCmpName); /* Display. */ for (gp = list; gp != NULL; gp = gp->next) { hPrintf("%s\n", gp->name); } hPrintf("</PRE></TT>"); }