e08ae97dc288749c2454fd98a10dc79f06e27cb5 max Tue Aug 11 06:16:20 2026 -0700 hgBlat/hgc: fixes from the v502 code review of the BLAT results pages, refs #37893 #4 blatOldTracks now falls back to "keep" (with a warning) on any value other than keep/hide/delete, instead of dropping into the destructive delete branch, so a typo in hg.conf can never silently discard a user's earlier BLAT tracks. #5 htmlEncode() (js/utils.js) now also escapes " and ', which the browser's text->markup conversion leaves alone. Every hgBlat caller puts the result in a double-quoted attribute, so an unescaped quote in the cart position string could break out of the attribute; the shared helper now honors its documented contract. #6 The non-BLAT alignment title no longer starts with a stray space. #7 open_memstream() is checked for NULL: on that failure the alignment renders straight to stdout instead of writing to a NULL FILE and calling fclose(NULL). The section reorder keys on the literal "
Here is the sequence around this feature: bases %d to %d of %s. " "The bases that contain the feature itself are in upper case.
\n", s, e, seqName); seq = hDnaFromSeq(database, seqName, s, e, dnaLower); toUpperN(seq->dna + (start-s), end - start); printf(""); cfm = cfmNew(10, 50, TRUE, FALSE, stdout, s); for (i=0; i"); } void printBand(char *chrom, int start, int end, boolean tableFormat) /* Print all matching chromosome bands. */ /* Ignore end if it is zero. */ { char sband[HDB_MAX_BAND_STRING], eband[HDB_MAX_BAND_STRING]; boolean gotS = FALSE; boolean gotE = FALSE; if (start < 0) return; gotS = hChromBand(database, chrom, start, sband); /* if the start lookup fails, don't bother with the end lookup */ if (!gotS) return; /* if no end chrom, print start band and exit */ if (end == 0) { if (tableFormat) printf("size; ++i) { cfmOut(cfm, seq->dna[i], 0); } cfmFree(&cfm); printf("
", eUrl, iframeOptions);
}
void printCustomUrlWithLabel(struct trackDb *tdb, char *itemName, char *itemLabel,
char *urlSetting, boolean encode, struct slPair *fields)
/* Print custom URL specified in trackDb settings. */
{
char urlLabelSetting[32];
// replace the $$ and other wildchards with the url given in tdb
char *url = getUrlSetting(tdb, urlSetting);
//char* eUrl = constructUrl(tdb, url, itemName, encode);
if (url==NULL || isEmpty(url))
return;
char *eUrl = replaceInUrl(url, itemName, cart, database, seqName, winStart, winEnd, tdb->track,
encode, fields);
if (eUrl==NULL)
return;
/* create the url label setting for trackDb from the url
setting prefix */
safef(urlLabelSetting, sizeof(urlLabelSetting), "%sLabel", urlSetting);
char *linkLabel = trackDbSettingOrDefault(tdb, urlLabelSetting, "Outside Link:");
char *eLinkLabel = replaceInUrl(linkLabel, itemName, cart, database, seqName, winStart, winEnd, tdb->track,
encode, fields);
// if we got no item name from hgTracks or the item name does not appear in the URL
// there is no need to show the item name at all
if (isEmpty(itemName) || !stringIn("$$", url))
{
printf("%s
",eUrl, eLinkLabel);
return;
}
printf("%s ",eLinkLabel);
printf("", eUrl);
if (sameWord(tdb->table, "npredGene"))
{
printf("%s (%s)
\n", itemName, "NCBI MapView");
}
else
{
char *label = itemName;
if (isNotEmpty(itemLabel) && differentString(itemName, itemLabel))
label = itemLabel;
printf("%s
The item \"%s\" has been located in other genomes:\n
Currently the item \"%s\" has not been located in another genome.\n",name);
}
void mafPrettyOut(FILE *f, struct mafAli *maf, int lineSize,
boolean onlyDiff, int blockNo, struct hash *hash);
void doAtom( struct trackDb *tdb, char *item)
{
char table[HDB_MAX_TABLE_STRING];
boolean hasBin;
//struct bed *bed;
char query[512];
struct sqlResult *sr;
char **row;
//boolean firstTime = TRUE;
int start = cartInt(cart, "o");
//struct sqlConnection *conn = hAllocConn(database);
char *user = cfgOption("db.user");
char *password = cfgOption("db.password");
struct sqlConnection *sc;
struct atom ret;
genericHeader(tdb, item);
if (!hFindSplitTable(database, seqName, tdb->table, table, sizeof table, &hasBin))
errAbort("mafPrettyOut track %s not found", tdb->table);
#if 0
sqlSafef(query, sizeof query, "select * from %s where name = '%s' and chrom = '%s' and chromStart = %d", table, escapedName, seqName, start);
sr = sqlGetResult(conn, query);
printf("This is the item you clicked on:
\n");
while ((row = sqlNextRow(sr)) != NULL)
{
if (firstTime)
firstTime = FALSE;
else
htmlHorizontalLine();
bed = bedLoadN(row+hasBin, 4);
bedPrintPos(bed, 4, tdb);
}
sqlFreeResult(&sr);
sqlSafef(query, sizeof query, "select * from %s where name = '%s'", table, escapedName);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
bed = bedLoadN(row+hasBin, 4);
if (bed->chromStart != start)
{
htmlHorizontalLine();
firstTime = FALSE;
printf("Another instances on %s:
\n",database);
bedPrintPos(bed, 4, tdb);
}
}
sqlFreeResult(&sr);
#endif
sc = sqlConnectRemote("localhost", user, password, "hgFixed");
sqlSafef(query, sizeof(query),
"select * from %s where name = '%s'", table, item);
sr = sqlGetResult(sc, query);
printf("Atom %s instances ('*' marks item you clicked on)
\n",item);
printf("
\n");
//printf("Ins#\tSpecies\t\tChrom\tStart\tEnd\tStrand\n");
printf( " # %-10s %-5s %12s %12s %10s %s %-10s %-10s\n",
"species","chrom", "start", "end", "length", "strand","fivePrime","threePrime");
while ((row = sqlNextRow(sr)) != NULL)
{
atomStaticLoad(row, &ret);
//atomOutput(&ret, stdout, '\t', '\n');
linkToOtherBrowser(ret.species, ret.chrom, ret.start, ret.end);
if (sameString(ret.chrom, seqName) && (start == ret.start) &&
sameString(ret.species, database))
printf("* ");
else
printf(" ");
printf( "%4d %-10s %-5s %12d %12d %10d %c %-10s %-10s\n",
ret.instance, ret.species,ret.chrom, ret.start + 1, ret.end,
ret.end - ret.start + 1, ret.strand[0],ret.fivePrime,ret.threePrime);
}
printf("");
sqlFreeResult(&sr);
if (!sameString("atom20080226d", table))
return;
printf("| ");
printf("Suh Trees \n"); printf(" ![]() ",item); printf(" | ![]() ",item); printf(" |
|---|---|
| ");
printf("NJ Trees \n"); printf(" ![]() ",item); printf(" | ![]() ",item); printf(" |
| ");
/*
printf("Gap UPGMA Trees \n"); printf(" ![]() ",item); printf(" | ![]() ",item); printf(" |
| "); char table[4096]; safef(table, sizeof(table), "%s", thisTbl->encodedTbl); int swapped = strSwapStrs(table, 4096, ";", " | |
| "); if (swapped == -1) errAbort("Error substituting ';' for ' | |
| "); if (swapped == -1) errAbort("Error substituting '|' for ' | ' in hgc.c:printEmbeddedTable()"); printf("%s |
%s
\n", description); printf("| "); char *toPrint = replaceChars(line, "\t", " | "); printf("%s", toPrint); printf(" |
\n
| \n"); else if (col->isList || col->isArray || col->lowType->stringy || asTypesIsInt(col->lowType->type)) printIdOrLinks(col, fieldToUrl, tdb, fields[ix]); else if (asTypesIsFloating(col->lowType->type)) { double valDouble = strtod(fields[ix],NULL); if (errno == 0 && valDouble != 0) printf(" | %g | \n", valDouble); else printf("%s | \n", fields[ix]); // decided not to print error } else printf("%s | \n", fields[ix]); printCount++; } if (skipIds) slFreeList(skipIds); if (sepFields) slFreeList(sepFields); if (embeddedTblFields) { printf("
\n");
printf("#match\tmisMatches\trepMatches\tnCount\tqNumInsert\tqBaseInsert\ttNumInsert\tBaseInsert\tstrand\tqName\tqSize\tqStart\tqEnd\ttName\ttSize\ttStart\ttEnd\tblockCount\tblockSizes\tqStarts\ttStarts\n");
for (psl = pslList; psl != NULL; psl = psl->next)
{
pslTabOut(psl, stdout);
}
printf("\n");
}
struct twoBitFile *getTwoBitFileFromUrlInSettings(struct trackDb *tdb, char *settingName)
/* Assume settingName is a URL to a two bit file and try and return it */
{
struct twoBitFile *tbf = NULL;
char *url = trackDbSetting(tdb, settingName);
if (url != NULL)
tbf = twoBitOpen(url);
return tbf;
}
struct twoBitFile *getOtherTwoBitUrl(struct trackDb *tdb)
/* Return open two bit file if otherTwoBitUrl setting is present */
{
return getTwoBitFileFromUrlInSettings(tdb, "otherTwoBitUrl");
}
struct psl *getPslAndSeq(struct trackDb *tdb, char *chromName, struct bigBedInterval *bb,
unsigned seqTypeField, DNA **retSeq, char **retCdsStr)
/* Read in psl and query sequence out of a bbiInverval on a give chromosome */
{
struct psl *psl= pslFromBigPsl(chromName, bb, seqTypeField, retSeq, retCdsStr);
DNA *dna = *retSeq;
if (dna == NULL)
{
struct twoBitFile *otherTbf = getOtherTwoBitUrl(tdb);
struct dnaSeq *seq = NULL;
if (otherTbf)
{
seq = twoBitReadSeqFrag(otherTbf, psl->qName, 0, 0);
if (seq)
*retSeq = dna = seq->dna;
}
}
return psl;
}
void genericBigPslClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, int end)
/* Handle click in big psl track. */
{
struct psl* pslList = NULL;
char *fileName = bbiNameFromSettingOrTable(tdb, conn, tdb->table);
struct bbiFile *bbi = bigBedFileOpenAlias(fileName, chromAliasFindAliases);
struct lm *lm = lmInit(0);
int ivStart = start, ivEnd = end;
if (start == end)
{
// item is an insertion; expand the search range from 0 bases to 2 so we catch it:
ivStart = max(0, start-1);
ivEnd++;
}
if (cfgOptionBooleanDefault("drawDot", FALSE))
bigPslDotPlot(tdb, bbi, seqName, winStart, winEnd);
boolean showEvery = sameString(item, "PrintAllSequences");
boolean showAll = trackDbSettingOn(tdb, "showAll");
unsigned seqTypeField = bbExtraFieldIndex(bbi, "seqType");
struct bigBedInterval *bb, *bbList = NULL;
// If showAll is on, show all alignments with this qName, not just the
// selected one.
if (showEvery)
{
struct bbiChromInfo *chrom, *chromList = bbiChromList(bbi);
for (chrom = chromList; chrom != NULL; chrom = chrom->next)
{
char *chromName = chrom->name;
int start = 0, end = chrom->size;
int itemsLeft = 0; // Zero actually means no limit....
struct bigBedInterval *intervalList = bigBedIntervalQuery(bbi, chromName,
start, end, itemsLeft, lm);
slCat(&bbList, intervalList);
}
}
else if (showAll)
{
int fieldIx;
struct bptFile *bpt = bigBedOpenExtraIndex(bbi, "name", &fieldIx);
bbList = bigBedNameQuery(bbi, bpt, fieldIx, item, lm);
}
else
bbList = bigBedIntervalQuery(bbi, seqName, ivStart, ivEnd, 0, lm);
/* print out extra fields */
for (bb = bbList; bb != NULL; bb = bb->next)
{
char *restFields[256];
int restCount = chopTabs(cloneString(bb->rest), restFields);
if (sameString(restFields[0], item))
{
/* print standard position information */
char *strand = restFields[2];
int bedSize = 25;
int restBedFields = bedSize - 3;
struct slPair *extraFieldPairs = NULL;
if (restCount > restBedFields)
{
char **extraFields = (restFields + restBedFields);
int extraFieldCount = restCount - restBedFields;
extraFieldPairs = getExtraFields(tdb, extraFields, extraFieldCount);
char *itemForUrl = getIdInUrl(tdb, item);
printCustomUrlWithFields(tdb, item, item, item == itemForUrl, extraFieldPairs);
if (itemForUrl)
printIframe(tdb, itemForUrl);
printPos(seqName, ivStart, ivEnd, strand, FALSE, item);
int printCount = extraFieldsPrint(tdb,NULL,extraFields, extraFieldCount);
printCount += 0;
}
}
}
char *bedRow[32];
char startBuf[16], endBuf[16];
int lastChromId = -1;
char chromName[bbi->chromBpt->keySize+1];
boolean firstTime = TRUE;
struct hash *seqHash = hashNew(0);
struct dyString *sequencesText = dyStringNew(256);
int sequencesFound = 0;
for (bb = bbList; bb != NULL; bb = bb->next)
{
bbiCachedChromLookup(bbi, bb->chromId, lastChromId, chromName, sizeof(chromName));
lastChromId=bb->chromId;
bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, 4);
if (showEvery || sameString(bedRow[3], item))
{
char *cdsStr, *seq;
struct psl *psl= getPslAndSeq(tdb, chromName, bb, seqTypeField, &seq, &cdsStr);
slAddHead(&pslList, psl);
// we're assuming that if there are multiple psl's with the same id that
// they are the same query sequence so we only put out one set of sequences
if (!hashLookup(seqHash, bedRow[3]) && !isEmpty(seq)) // if there is a query sequence
{
if (firstTime)
{
firstTime = FALSE;
printf("| Q1 | %f |
| median | %f |
| Q3 | %f |
| average | %f |
| min | %f |
| max | %f |
| count | %d |
| total | %f |
| standard deviation | %f |
| %s Position | %s Position | Bases | Alignment |
| %s | %s | %.*s | ", hilite, ourPos, otherPos, hr->otherBaseCount, hr->otherBases); hgcAnchorSomewhereExt("htcChainAli", item, tdb->track, chain->tName, hr->chromStart - 10, hr->chromEnd + 10, tdb->track); printf("alignment |
| %s Position | %s Position | Bases | Alignment |
| %s | %s | %.*s | ", hilite, ourPos, otherPos, hr->baseCount, hr->bases); hgcAnchorSomewhereExt("htcChainAli", item, tdb->track, chain->tName, hr->chromStart - 10, hr->chromEnd + 10, tdb->track); printf("alignment |
| %s Position | %s Position | # Bases in %s | #Bases in %s | Alignment |
| %s | %s | %d | %d | ", hilite, ourPos, otherPos, hr->baseCount, hr->otherBaseCount); hgcAnchorSomewhereExt("htcChainAli", item, tdb->track, chain->tName, hr->chromStart - 10, hr->chromEnd + 10, tdb->track); printf("alignment |
| %s Position | %s Position | Change | Alignment |
| %s | %s | %.*s -> %.*s | ", hilite, ourPos, otherPos, hr->otherBaseCount, hr->otherBases, hr->baseCount, hr->bases); hgcAnchorSomewhereExt("htcChainAli", item, tdb->track, chain->tName, hr->chromStart - 10, hr->chromEnd + 10, tdb->track); printf("alignment |
"); if (dbIsFound) puts("Note: The \"Mask repeats\" option applies only to \"Get DNA\", not to \"Extended case/color options\".
"); } boolean dnaIgnoreTrack(char *track) /* Return TRUE if this is one of the tracks too boring * to put DNA on. */ { return (sameString("cytoBand", track) || sameString("gcPercent", track) || sameString("gold", track) || sameString("gap", track) || startsWith("mouseSyn", track)); } struct customTrack *getCtList() /* initialize theCtList if necessary and return it */ { if (theCtList == NULL) theCtList = customTracksParseCart(database, cart, NULL, NULL); return(theCtList); } struct trackDb *tdbForCustomTracks() /* Load custom tracks (if any) and translate to list of trackDbs */ { struct customTrack *ctList = getCtList(); struct customTrack *ct; struct trackDb *tdbList = NULL, *tdb; for (ct=ctList; ct != NULL; ct=ct->next) { AllocVar(tdb); tdb->track = ct->tdb->track; tdb->table = ct->tdb->table; tdb->shortLabel = ct->tdb->shortLabel; tdb->type = ct->tdb->type; tdb->longLabel = ct->tdb->longLabel; tdb->visibility = ct->tdb->visibility; tdb->priority = ct->tdb->priority; tdb->colorR = ct->tdb->colorR; tdb->colorG = ct->tdb->colorG; tdb->colorB = ct->tdb->colorB; tdb->altColorR = ct->tdb->altColorR; tdb->altColorG = ct->tdb->altColorG; tdb->altColorB = ct->tdb->altColorB; tdb->useScore = ct->tdb->useScore; tdb->private = ct->tdb->private; tdb->url = ct->tdb->url; tdb->grp = ct->tdb->grp; tdb->canPack = ct->tdb->canPack; trackDbPolish(tdb); slAddHead(&tdbList, tdb); } slReverse(&tdbList); return(tdbList); } static struct trackDb *getCustomTrackTdb(char *table) /* Find the trackDb structure for a custom track table. */ { struct customTrack *ctList = getCtList(); struct customTrack *ct = NULL; for (ct = ctList; ct != NULL; ct = ct->next) if (sameString(table, ct->tdb->track)) return ct->tdb; return NULL; } struct trackDb *getTdbForTrackName(char *trackName) /* Given a track name (which may have ct_ or hub_ prepended), tdb */ { assert(trackHash != NULL); if (isCustomTrack(trackName)) return getCustomTrackTdb(trackName); else if (isHubTrack(trackName)) return hubConnectAddHubForTrackAndFindTdb( database, trackName, NULL, trackHash); else return hashMustFindVal(trackHash, trackName); } struct customTrack *lookupCt(char *name) /* Return custom track for name, or NULL. */ { struct customTrack *ct; for (ct=getCtList(); ct != NULL; ct=ct->next) if (sameString(name, ct->tdb->track)) return(ct); return(NULL); } void parseSs(char *ss, char **retPslName, char **retFaName, char **retQName) /* Parse space separated 'ss' item. */ { static char buf[512*2]; int wordCount; char *words[4]; strcpy(buf, ss); wordCount = chopLine(buf, words); if (wordCount < 1) errAbort("Empty user cart variable ss."); *retPslName = words[0]; if (retFaName != NULL) { if (wordCount < 2) errAbort("Expecting psl filename and fa filename in cart variable ss, but only got one word: %s", ss); *retFaName = words[1]; } if (retQName != NULL) { if (wordCount < 3) errAbort("Expecting psl filename, fa filename and query name in cart variable ss, but got this: %s", ss); *retQName = words[2]; } } boolean ssFilesExist(char *ss) /* Return TRUE if both files in ss exist. -- Copied from hgTracks! */ { char *faFileName, *pslFileName; parseSs(ss, &pslFileName, &faFileName, NULL); return fileExists(pslFileName) && fileExists(faFileName); } struct trackDb *tdbForUserPsl() /* Load up user's BLAT results into trackDb. */ { char *ss = cartOptionalString(cart, "ss"); if ((ss != NULL) && !ssFilesExist(ss)) { ss = NULL; cartRemove(cart, "ss"); } if (ss == NULL) return(NULL); else { struct trackDb *tdb; AllocVar(tdb); tdb->track = cloneString(USER_PSL_TRACK_NAME); tdb->table = cloneString(USER_PSL_TRACK_NAME); tdb->shortLabel = cloneString(USER_PSL_TRACK_LABEL); tdb->type = cloneString("psl"); tdb->longLabel = cloneString(USER_PSL_TRACK_LONGLABEL); tdb->visibility = tvFull; tdb->priority = 11.0; trackDbPolish(tdb); return(tdb); } } struct trackDb *rFindUnderstandableTrack(char *db, struct trackDb *tdb) // If any leaf is usable in getting DNA then that leaf's tdb is returned. { if (tdb->subtracks != NULL) return rFindUnderstandableTrack(db,tdb->subtracks); if (fbUnderstandTrack(db, tdb) && !dnaIgnoreTrack(tdb->table)) return tdb; else return NULL; } boolean forestHasUnderstandableTrack(char *db, struct trackDb *tdb) // TRUE if any leaf is usable in getting DNA. { return (rFindUnderstandableTrack(db, tdb) != NULL); } struct trackDb* loadTracks() /* load native tracks, cts, userPsl and track Hubs and return tdbList */ { struct trackDb *tdbList = hTrackDb(database); struct trackDb *ctdbList = tdbForCustomTracks(); struct trackDb *utdbList = tdbForUserPsl(); struct grp *pGrpList = NULL; struct trackDb *hubList = hubCollectTracks(database, &pGrpList); ctdbList = slCat(ctdbList, tdbList); ctdbList = slCat(ctdbList, hubList); tdbList = slCat(utdbList, ctdbList); return tdbList; } static boolean parseDnaPos(char *db, char *pos, char **retChrom, int *retStart, int *retEnd) /* Parse a position string that may be chrom:start-end or just chrom:pos (single base). */ { if (hgParseChromRange(db, pos, retChrom, retStart, retEnd)) return TRUE; /* check for single position like chrX:67774500 (colon but no dash) */ char *colon = strchr(pos, ':'); if (colon != NULL && strchr(colon, '-') == NULL) { struct dyString *dy = dyStringCreate("%s-%s", pos, colon + 1); boolean result = hgParseChromRange(db, dy->string, retChrom, retStart, retEnd); dyStringFree(&dy); return result; } return FALSE; } void doGetDnaExtended1() /* Do extended case/color get DNA options. */ { boolean revComp = cartUsualBoolean(cart, "hgSeq.revComp", FALSE); boolean maskRep = cartUsualBoolean(cart, "hgSeq.maskRepeats", FALSE); int padding5 = cartUsualInt(cart, "hgSeq.padding5", 0); int padding3 = cartUsualInt(cart, "hgSeq.padding3", 0); int lineWidth = cartUsualInt(cart, "lineWidth", 60); char *casing = cartUsualString(cart, "hgSeq.casing", ""); char *repMasking = cartUsualString(cart, "hgSeq.repMasking", ""); boolean caseUpper= FALSE; char *pos = NULL; struct trackDb *tdbList = loadTracks(); cartWebStart(cart, database, "Extended DNA Case/Color"); if (NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos")))) parseDnaPos(database, pos, &seqName, &winStart, &winEnd); if (winEnd - winStart > 5000000) { printf("Please zoom in to 5 million bases or less to color the DNA"); return; } printf("
"); if (cgiBooleanDefined("hgSeq.maskRepeats")) cartSetBoolean(cart, "hgSeq.maskRepeats", maskRep); if (*repMasking != 0) cartSetString(cart, "hgSeq.repMasking", repMasking); if (maskRep) { struct trackDb *rtdb; char *visString = cartOptionalString(cart, "rmsk"); for (rtdb = tdbList; rtdb != NULL; rtdb=rtdb->next) { if (startsWith(rtdb->table, "rmsk")) break; } printf("
Note: repeat masking style from previous page will not apply to this page.\n"); if ((rtdb != NULL) && ((visString == NULL) || !sameString(visString, "hide"))) printf("Use the case/color options for the RepeatMasker track below.
\n"); else printf("Unhide the RepeatMasker track in the genome browser, then return to this page and use the case/color options for the RepeatMasker track below.
\n"); } cartSetInt(cart, "padding5", padding5); cartSetInt(cart, "padding3", padding3); if (sameString(casing, "upper")) caseUpper = TRUE; if (*casing != 0) cartSetString(cart, "hgSeq.casing", casing); printf("
\n"); printf("Copying and pasting the web page output to a text editor such as Word " "will retain upper case but lose colors and other formatting. That is still " "useful because other web tools such as " "NCBI Blast " "can be set to ignore lower case. To fully capture formatting such as color " "and underlining, view the output as \"source\" in your web browser, or download " "it, or copy the output page into an html editor.
"); puts("The default line width of 60 characters is standard, but if you have " "a reasonable sized monitor it's useful to set this higher - to 125 characters " "or more. You can see more DNA at once this way, and fewer line breaks help " "in finding DNA strings using the web browser search function.
"); puts("Be careful about requesting complex formatting for a very large " "chromosomal region. After all the html tags are added to the output page, " "the file size may exceed size limits that your browser, clipboard, and " "other software can safely display. The tool will format 10 Mb and more, however.
"); trackDbFreeList(&tdbList); } void doGetBlastPep(char *readName, char *table) /* get predicted protein */ { int qStart; struct psl *psl; int start, end; struct sqlResult *sr; struct sqlConnection *conn = hAllocConn(database); struct dnaSeq *tSeq; char query[256], **row; char fullTable[HDB_MAX_TABLE_STRING]; boolean hasBin; char *buffer, *str; int i, j; char *ptr; start = cartInt(cart, "o"); if (!hFindSplitTable(database, seqName, table, fullTable, sizeof fullTable, &hasBin)) errAbort("doGetBlastPep track %s not found", table); sqlSafef(query, sizeof query, "select * from %s where qName = '%s' and tName = '%s' and tStart=%d", fullTable, readName, seqName, start); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) == NULL) errAbort("Couldn't find alignment for %s at %d", readName, start); psl = pslLoad(row+hasBin); sqlFreeResult(&sr); hFreeConn(&conn); printf("");
end = psl->tEnd;
if (psl->strand[1] == '+')
end = psl->tStarts[psl->blockCount - 1] + psl->blockSizes[psl->blockCount - 1] *3;
if ((ptr = strchr(readName, '.')) != NULL)
*ptr++ = 0;
printf(">%s-%s\n", readName,database);
tSeq = hDnaFromSeq(database, psl->tName, start, end, dnaLower);
if (psl->strand[1] == '-')
{
start = psl->tSize - end;
reverseComplement(tSeq->dna, tSeq->size);
}
str = buffer = needMem(psl->qSize + 1);
qStart = 0;
for (i=0; iblockCount; ++i)
{
int ts = psl->tStarts[i] - start;
int sz = psl->blockSizes[i];
for (;qStart < psl->qStarts[i]; qStart++)
*str++ = 'X';
for (j=0; jdna[codonStart];
if ((*str = lookupCodon(codon)) == 0)
*str = '*';
str++;
qStart++;
}
}
*str = 0;
printLines(stdout, buffer, 50);
printf(" ");
}
void doGetDna2()
/* Do second DNA dialog (or just fetch DNA) */
{
char *tbl = cgiUsualString("table", "");
char *action = cgiUsualString("submit", "");
int itemCount;
char *pos = NULL;
char *chrom = NULL;
int start = 0;
int end = 0;
if (sameString(action, EXTENDED_DNA_BUTTON))
{
doGetDnaExtended1();
return;
}
// This output probably should be just text/plain but
// trying to support the fancy warn handler box requires html.
// But we want to keep it very simple and close to a plain text dump.
cartHtmlStart("DNA");
puts("");
if (tbl[0] == 0)
{
itemCount = 1;
if ( NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos"))) &&
parseDnaPos((dbIsFound ? database : NULL), pos, &chrom, &start, &end))
{
hgSeqRange(database, chrom, start, end, '?', "dna");
}
else
{
hgSeqRange(database, seqName, cartInt(cart, "l"), cartInt(cart, "r"),
'?', "dna");
}
}
else
{
struct hTableInfo *hti = NULL;
char rootName[HDB_MAX_TABLE_STRING];
char parsedChrom[HDB_MAX_CHROM_STRING];
/* use the values from the dnaPos dialog box */
if (!( NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos"))) &&
parseDnaPos(database, pos, &chrom, &start, &end)))
{
/* if can't get DnaPos from dialog box, use "o" and "t" */
start = cartInt(cart, "o");
end = cartInt(cart, "t");
}
else
{
seqName = chrom;
}
/* Table might be a custom track if it's not in the database,
* or bigBed if it is in the database but has only one column called 'fileName';
* in which case, just get DNA as if no table were given. */
hParseTableName(database, tbl, rootName, parsedChrom);
if (!trackHubDatabase(database))
hti = hFindTableInfo(database, seqName, rootName);
if (hti == NULL || hti->startField[0] == 0)
{
itemCount = 1;
hgSeqRange(database, seqName, start, end, '?', tbl);
}
else
{
char *where = NULL;
char *item = cgiUsualString("i", "");
char buf[256];
if ((hti->nameField[0] != 0) && (item[0] != 0))
{
sqlSafef(buf, sizeof(buf), "%s = '%s'", hti->nameField, item);
where = buf;
}
itemCount = hgSeqItemsInRange(database, tbl, seqName, start, end, where);
}
}
if (itemCount == 0)
printf("\n# No results returned from query.\n\n");
puts("");
}
struct hTableInfo *ctToHti(struct customTrack *ct)
/* Create an hTableInfo from a customTrack. */
{
struct hTableInfo *hti;
AllocVar(hti);
hti->rootName = cloneString(ct->tdb->table);
hti->isPos = TRUE;
hti->isSplit = FALSE;
hti->hasBin = FALSE;
hti->type = cloneString(ct->tdb->type);
int fieldCount = 3;
if (sameWord(ct->dbTrackType, "bedDetail"))
fieldCount = ct->fieldCount - 2;
else if (sameWord(ct->dbTrackType, "pgSnp"))
fieldCount = 4;
else
fieldCount = ct->fieldCount;
if (fieldCount >= 3)
{
strncpy(hti->chromField, "chrom", 32);
strncpy(hti->startField, "chromStart", 32);
strncpy(hti->endField, "chromEnd", 32);
}
if (fieldCount >= 4)
{
strncpy(hti->nameField, "name", 32);
}
if (fieldCount >= 5)
{
strncpy(hti->scoreField, "score", 32);
}
if (fieldCount >= 6)
{
strncpy(hti->strandField, "strand", 32);
}
if (fieldCount >= 8)
{
strncpy(hti->cdsStartField, "thickStart", 32);
strncpy(hti->cdsEndField, "thickEnd", 32);
hti->hasCDS = TRUE;
}
if (fieldCount >= 12)
{
strncpy(hti->countField, "blockCount", 32);
strncpy(hti->startsField, "chromStarts", 32);
strncpy(hti->endsSizesField, "blockSizes", 32);
hti->hasBlocks = TRUE;
}
return(hti);
}
struct hTableInfo *htiForUserPsl()
/* Create an hTableInfo for user's BLAT results. */
{
struct hTableInfo *hti;
AllocVar(hti);
hti->rootName = cloneString(USER_PSL_TRACK_NAME);
hti->isPos = TRUE;
hti->isSplit = FALSE;
hti->hasBin = FALSE;
hti->type = cloneString("psl");
strncpy(hti->chromField, "tName", 32);
strncpy(hti->startField, "tStart", 32);
strncpy(hti->endField, "tEnd", 32);
strncpy(hti->nameField, "qName", 32);
/* psl can be scored... but strictly speaking, does not have a score field! */
strncpy(hti->strandField, "strand", 32);
hti->hasCDS = FALSE;
strncpy(hti->countField, "blockCount", 32);
strncpy(hti->startsField, "tStarts", 32);
strncpy(hti->endsSizesField, "tSizes", 32);
hti->hasBlocks = TRUE;
return(hti);
}
struct bed *bedFromUserPsl()
/* Load up user's BLAT results into bedList. */
{
struct bed *bedList = NULL;
char *ss = cartOptionalString(cart, "ss");
if ((ss != NULL) && ! ssFilesExist(ss))
{
ss = NULL;
cartRemove(cart, "ss");
}
if (ss == NULL)
return(NULL);
else
{
struct lineFile *f;
struct psl *psl;
enum gfType qt, tt;
char *faFileName, *pslFileName;
int i;
parseSs(ss, &pslFileName, &faFileName, NULL);
pslxFileOpen(pslFileName, &qt, &tt, &f);
while ((psl = pslNext(f)) != NULL)
{
struct bed *bed;
AllocVar(bed);
bed->chrom = cloneString(seqName);
bed->chromStart = psl->tStart;
bed->chromEnd = psl->tEnd;
bed->name = cloneString(psl->qName);
bed->score = pslScore(psl);
if ((psl->strand[0] == '-' && psl->strand[1] == '+') ||
(psl->strand[0] == '+' && psl->strand[1] == '-'))
strncpy(bed->strand, "-", 2);
else
strncpy(bed->strand, "+", 2);
bed->thickStart = bed->chromStart;
bed->thickEnd = bed->chromEnd;
bed->blockCount = psl->blockCount;
bed->chromStarts = needMem(bed->blockCount * sizeof(int));
bed->blockSizes = needMem(bed->blockCount * sizeof(int));
for (i=0; i < bed->blockCount; i++)
{
bed->chromStarts[i] = psl->tStarts[i];
bed->blockSizes[i] = psl->blockSizes[i];
}
if (qt == gftProt)
for (i=0; i < bed->blockCount; i++)
{
/* If query is protein, blockSizes are in aa units; fix 'em. */
bed->blockSizes[i] *= 3;
}
if (psl->strand[1] == '-')
{
/* psl: if target strand is '-', flip the coords.
* (this is the target part of pslRc from src/lib/psl.c) */
for (i=0; i < bed->blockCount; ++i)
{
bed->chromStarts[i] =
psl->tSize - (bed->chromStarts[i] +
bed->blockSizes[i]);
}
reverseInts(bed->chromStarts, bed->blockCount);
reverseInts(bed->blockSizes, bed->blockCount);
assert(bed->chromStart == bed->chromStarts[0]);
}
/* translate absolute starts to relative starts (after handling
* target-strand coord-flipping) */
for (i=0; i < bed->blockCount; i++)
{
bed->chromStarts[i] -= bed->chromStart;
}
slAddHead(&bedList, bed);
pslFree(&psl);
}
lineFileClose(&f);
slReverse(&bedList);
return(bedList);
}
}
void addColorToRange(int r, int g, int b, struct rgbColor *colors, int start, int end)
/* Add rgb values to colors array from start to end. Don't let values
* exceed 255 */
{
struct rgbColor *c;
int rr, gg, bb;
int i;
for (i=start; i");
printf(">%s:%d-%d %s\n", seqName, winStart+1, winEnd,
(isRc ? "(reverse complement)" : ""));
seq = hDnaFromSeq(database, seqName, winStart, winEnd, dnaLower);
if (isRc)
reverseComplement(seq->dna, seq->size);
if (defaultUpper)
touppers(seq->dna);
AllocArray(colors, winSize);
struct trackDb* tdb;
for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
{
char *track = tdb->track;
char *table = tdb->table;
struct featureBits *fbList = NULL, *fb;
struct customTrack *ct = lookupCt(track);
if (sameString(USER_PSL_TRACK_NAME, table)
|| ct != NULL
|| ( tdbVisLimitedByAncestors(cart,tdb,TRUE,TRUE) != tvHide
&& forestHasUnderstandableTrack(database, tdb) ) )
{
char buf[256];
int r,g,b;
/* to save a LOT of time, don't fetch track features unless some
* coloring/formatting has been specified for them. */
boolean hasSettings = FALSE;
safef(buf, sizeof(buf), "%s_u", track);
hasSettings |= cgiBoolean(buf);
safef(buf, sizeof(buf), "%s_b", track);
hasSettings |= cgiBoolean(buf);
safef(buf, sizeof(buf), "%s_i", track);
hasSettings |= cgiBoolean(buf);
safef(buf, sizeof(buf), "%s_case", track);
hasSettings |= cgiBoolean(buf);
safef(buf, sizeof(buf), "%s_red", track);
hasSettings |= (cgiOptionalInt(buf, 0) != 0);
safef(buf, sizeof(buf), "%s_green", track);
hasSettings |= (cgiOptionalInt(buf, 0) != 0);
safef(buf, sizeof(buf), "%s_blue", track);
hasSettings |= (cgiOptionalInt(buf, 0) != 0);
if (! hasSettings)
continue;
if (sameString(USER_PSL_TRACK_NAME, track))
{
struct hTableInfo *hti = htiForUserPsl();
struct bedFilter *bf;
struct bed *bedList, *bedList2;
AllocVar(bf);
bedList = bedFromUserPsl();
bedList2 = bedFilterListInRange(bedList, bf, seqName, winStart,
winEnd);
fbList = fbFromBed(database, track, hti, bedList2, winStart, winEnd,
TRUE, FALSE);
bedFreeList(&bedList);
bedFreeList(&bedList2);
}
else if (ct != NULL)
{
struct hTableInfo *hti = ctToHti(ct);
struct bedFilter *bf;
struct bed *bedList2, *ctBedList = NULL;
AllocVar(bf);
if (ct->dbTrack && (!sameString(tdb->type, "vcf")))
{
struct bed *bed;
int fieldCount = ct->fieldCount;
if ((ct->dbTrackType != NULL) && sameString(ct->dbTrackType, "pgSnp"))
fieldCount = 4;
char query[512];
int rowOffset;
char **row;
struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
struct sqlResult *sr = NULL;
sqlSafef(query, sizeof(query), "select * from %s", ct->dbTableName);
sr = hRangeQuery(conn, ct->dbTableName, seqName,
winStart, winEnd, NULL, &rowOffset);
while ((row = sqlNextRow(sr)) != NULL)
{
bed = bedLoadN(row+rowOffset, fieldCount);
if (bf == NULL || bedFilterOne(bf, bed))
{
struct bed *copy = cloneBed(bed);
slAddHead(&ctBedList, copy);
}
}
sqlFreeResult(&sr);
hFreeConn(&conn);
}
else if (sameString(ct->dbTrackType, "bigBed"))
{
struct lm *lm = lmInit(0);
struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(ct->bbiFile, seqName, winStart, winEnd, 0, lm);
char *bedRow[32];
char startBuf[16], endBuf[16];
for (bb = bbList; bb != NULL; bb = bb->next)
{
bigBedIntervalToRow(bb, seqName, startBuf, endBuf, bedRow, ArraySize(bedRow));
struct bed *bed = bedLoadN(bedRow, ct->bbiFile->definedFieldCount);
slAddHead(&ctBedList, bed);
}
}
else
{
ctBedList = ct->bedList;
}
if (startsWith("vcf", tdb->type))
{
fbList = vcfLoadInterval(ct->tdb, winStart, winEnd);
}
else
{
bedList2 = bedFilterListInRange(ctBedList, bf, seqName, winStart,
winEnd);
fbList = fbFromBed(database, track, hti, bedList2, winStart, winEnd,
TRUE, FALSE);
bedFreeList(&bedList2);
}
if (!ct->bedList)
bedFreeList(&ctBedList);
}
else
{
if (tdb->subtracks)
{
struct slRef *refLeaves = trackDbListGetRefsToDescendantLeaves(tdb->subtracks);
struct slRef *refLeaf = NULL;
while ((refLeaf = slPopHead(&refLeaves)) != NULL)
{
struct trackDb *tdbLeaf = refLeaf->val;
if (tdbVisLimitedByAncestors(cart,tdbLeaf,TRUE,TRUE) != tvHide
&& fbUnderstandTrack(database, tdbLeaf)
&& !dnaIgnoreTrack(tdbLeaf->table))
{
struct featureBits *fbLeafList;
if (startsWith("vcf", tdbLeaf->type))
fbLeafList = vcfLoadInterval(tdbLeaf, winStart, winEnd);
else if (startsWith("big", tdbLeaf->type))
fbLeafList = getBigBedFbList(tdbLeaf, seqName, winStart, winEnd);
else
fbLeafList = fbGetRange(database, tdbLeaf->table, seqName, winStart, winEnd);
if (fbLeafList != NULL)
fbList = slCat(fbList,fbLeafList);
}
freeMem(refLeaf);
}
}
else
{
if (startsWith("vcf", tdb->type))
fbList = vcfLoadInterval(tdb, winStart, winEnd);
else if (startsWith("big", tdb->type))
fbList = getBigBedFbList(tdb, seqName, winStart, winEnd);
else
fbList = fbGetRange(database, tdb->table, seqName, winStart, winEnd);
}
}
/* Flip underline/italic/bold bits. */
getDnaHandleBits(track, "u", uBits, winStart, winEnd, isRc, fbList);
getDnaHandleBits(track, "b", bBits, winStart, winEnd, isRc, fbList);
getDnaHandleBits(track, "i", iBits, winStart, winEnd, isRc, fbList);
/* Toggle case if necessary. */
safef(buf, sizeof buf, "%s_case", track);
if (cgiBoolean(buf))
{
for (fb = fbList; fb != NULL; fb = fb->next)
{
DNA *dna;
int start = fb->start - winStart;
int end = fb->end - winStart;
int size = fb->end - fb->start;
if (isRc)
reverseIntRange(&start, &end, seq->size);
dna = seq->dna + start;
if (defaultUpper)
toLowerN(dna, size);
else
toUpperN(dna, size);
}
}
/* Add in RGB values if necessary. */
safef(buf, sizeof buf, "%s_red", track);
r = cartInt(cart, buf);
safef(buf, sizeof buf, "%s_green", track);
g = cartInt(cart, buf);
safef(buf, sizeof buf, "%s_blue", track);
b = cartInt(cart, buf);
if (r != 0 || g != 0 || b != 0)
{
for (fb = fbList; fb != NULL; fb = fb->next)
{
int s = fb->start - winStart;
int e = fb->end - winStart;
if (isRc)
reverseIntRange(&s, &e, winEnd - winStart);
addColorToRange(r, g, b, colors, s, e);
}
}
}
}
cfm = cfmNew(0, lineWidth, FALSE, FALSE, stdout, 0);
for (i=0; isize; ++i)
{
struct rgbColor *color = colors+i;
int c = (color->r<<16) + (color->g<<8) + color->b;
cfmOutExt(cfm, seq->dna[i], c,
bitReadOne(uBits, i), bitReadOne(bBits, i), bitReadOne(iBits, i));
}
cfmFree(&cfm);
freeDnaSeq(&seq);
bitFree(&uBits);
bitFree(&iBits);
bitFree(&bBits);
}
void medlineLinkedTermLine(char *title, char *text, char *search, char *keyword)
/* Produce something that shows up on the browser as
* TITLE: value
* with the value hyperlinked to medline using a specified search term. */
{
char *encoded = cgiEncode(search);
char *encodedKeyword = cgiEncode(keyword);
printf("%s: ", title);
if (sameWord(text, "n/a") || sameWord(text, "none"))
printf("n/a
\n");
else
{
printf("%s
\n", text);
}
freeMem(encoded);
}
void medlineLinkedLine(char *title, char *text, char *search)
/* Produce something that shows up on the browser as
* TITLE: value
* with the value hyperlinked to medline. */
{
char *encoded = cgiEncode(search);
printf("%s: ", title);
if (sameWord(text, "n/a"))
printf("n/a
\n");
else
{
printf("%s
\n", text);
}
freeMem(encoded);
}
void medlineProductLinkedLine(char *title, char *text)
/* Produce something that shows up on the browser as
* TITLE: value
* with the value hyperlinked to medline.
* Replaces commas in the product name with spaces, as commas sometimes
* interfere with PubMed search */
{
subChar(text, ',', ' ');
medlineLinkedLine(title, text, text);
}
void appendAuthor(struct dyString *dy, char *gbAuthor, int len)
/* Convert from Kent,W.J. to Kent WJ and append to dy.
* gbAuthor gets eaten in the process.
* Also strip web URLs since Entrez doesn't like those. */
{
char buf[MAXURLSIZE];
char *ptr;
if (len >= sizeof(buf))
warn("author %s too long to process", gbAuthor);
else
{
memcpy(buf, gbAuthor, len);
buf[len] = 0;
stripChar(buf, '.');
subChar(buf, ',' , ' ');
if ((ptr = strstr(buf, " http://")) != NULL)
*ptr = 0;
if ((ptr = strstr(buf, " https://")) != NULL)
*ptr = 0;
dyStringAppend(dy, buf);
dyStringAppend(dy, " ");
}
}
void gbToEntrezAuthor(char *authors, struct dyString *dy)
/* Convert from Genbank author format:
* Kent,W.J., Haussler,D. and Zahler,A.M.
* to Entrez search format:
* Kent WJ,Haussler D,Zahler AM
*/
{
char *s = authors, *e;
/* Parse first authors, which will be terminated by '.,' */
while ((e = strstr(s, ".,i ")) != NULL)
{
int len = e - s + 1;
appendAuthor(dy, s, len);
s += len+2;
}
if ((e = strstr(s, " and")) != NULL)
{
int len = e - s;
appendAuthor(dy, s, len);
s += len+4;
}
if ((s = skipLeadingSpaces(s)) != NULL && s[0] != 0)
{
int len = strlen(s);
appendAuthor(dy, s, len);
}
}
/* --- !!! Riken code is under development Fan. 4/16/02 */
void printRikenInfo(char *acc, struct sqlConnection *conn )
/* Print Riken annotation info */
{
struct sqlResult *sr;
char **row;
char query[512];
char *seqid, *accession, *comment;
// char *qualifier, *anntext, *datasrc, *srckey, *href, *evidence;
accession = acc;
sqlSafef(query, sizeof(query),
"select seqid from rikenaltid where altid='%s';", accession);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
{
seqid=cloneString(row[0]);
sqlSafef(query, sizeof(query),
"select Qualifier, Anntext, Datasrc, Srckey, Href, Evidence "
"from rikenann where seqid='%s';", seqid);
sqlFreeResult(&sr);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
while (row !=NULL)
{
// qualifier = row[0]; unused variable
// anntext = row[1]; unused variable
// datasrc = row[2]; unused variable
// srckey = row[3]; unused variable
// href = row[4]; unused variable
// evidence = row[5]; unused variable
row = sqlNextRow(sr);
}
sqlSafef(query, sizeof(query),
"select comment from rikenseq where id='%s';", seqid);
sqlFreeResult(&sr);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
{
comment = row[0];
printf("Riken/comment: %s
\n",comment);
}
}
}
void printGeneCards(char *db, char *geneName)
/* Print out a link to GeneCards (Human only).
* Caller passes the assembly db so quickLifted callers can pass the source
* (quickLiftDb) rather than the destination hub_NNN_. */
{
if (startsWith("hg", db) && isNotEmpty(geneName))
{
printf("GeneCards: "
"%s
\n",
geneName, geneName);
}
}
int getImageId(struct sqlConnection *conn, char *acc)
/* get the image id for a clone, or 0 if none */
{
int imageId = 0;
if (sqlTableExists(conn, imageCloneTable))
{
struct sqlResult *sr;
char **row;
char query[128];
sqlSafef(query, sizeof(query),
"select imageId from %s where acc = '%s'",imageCloneTable, acc);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
imageId = sqlUnsigned(row[0]);
sqlFreeResult(&sr);
}
return imageId;
}
void htcDisplayMrna(char *acc)
/* Display mRNA available from genback or seq table.. */
{
struct dnaSeq *seq = hGenBankGetMrna(database, acc, NULL);
if (seq == NULL)
errAbort("mRNA sequence %s not found", acc);
cartHtmlStart("mRNA sequence");
printf("");
faWriteNext(stdout, seq->name, seq->dna, seq->size);
printf("");
dnaSeqFree(&seq);
}
static int getEstTranscriptionDir(struct sqlConnection *conn, struct psl *psl)
/* get the direction of transcription for an EST; return splice support count */
{
char query[256], estOrient[64];
sqlSafef(query, sizeof(query),
"select intronOrientation from %s.estOrientInfo where chrom = '%s' and chromStart = %d and name = '%s'",
database, psl->tName, psl->tStart, psl->qName);
if (sqlQuickQuery(conn, query, estOrient, sizeof(estOrient)) != NULL)
return sqlSigned(estOrient) * ((psl->strand[0] == '+') ? 1 : -1);
else
return 0;
}
static struct gbWarn *checkGbWarn(struct sqlConnection *conn, char *acc)
/* check if there is a gbWarn entry for this accession, return NULL if none */
{
struct gbWarn *gbWarn = NULL;
if (sqlTableExists(conn, gbWarnTable))
gbWarn = sqlQueryObjs(conn, (sqlLoadFunc)gbWarnLoad, sqlQuerySingle,
"SELECT * FROM %s WHERE acc = \"%s\"", gbWarnTable, acc);
return gbWarn;
}
static void printGbWarn(char *acc, struct gbWarn *gbWarn)
/* print descriptive information about an accession in the gbWarn table */
{
char *msg = NULL;
switch (gbWarn->reason) {
case gbWarnInvitroNorm:
msg = "is from the InVitroGen/Genoscope full-length library. Some of the entries "
"associated with this dataset appear to have been aligned to the reference "
"genome and the sequences subsequently modified to match the genome. This "
"process may have resulted in apparent high-quality alignments to pseudogenes.";
break;
case gbWarnAthRage:
msg = "is from the Athersys RAGE library. These sequences were created by inducing expression and may not "
"be an indication of in vivo expression.";
break;
case gbWarnOrestes:
msg = "is from an ORESTES library. This protocol includes a PCR step subject to genomic contamination.";
break;
}
assert(msg != NULL);
char *msg2= "Care should be taken in using alignments of this sequence as evidence of transcription.";
printf("Warning: %s %s %s
\n", acc, msg, msg2);
}
static void printRnaSpecs(struct trackDb *tdb, char *acc, struct psl *psl)
/* Print auxiliarry info on RNA. */
{
struct dyString *dy = dyStringNew(1024);
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2= hAllocConn(database);
struct sqlResult *sr;
char **row;
char rgdEstId[512];
char query[256];
char *type,*direction,*orgFullName,*library,*clone,*sex,*tissue,
*development,*cell,*cds,*description, *author,*geneName,
*date,*productName;
// char *source; unused variable
// int seqSize,fileSize; unused variables
// long fileOffset; unused variable
// char *extFile; unused variable
boolean hasVersion = hHasField(database, gbCdnaInfoTable, "version");
boolean haveGbSeq = sqlTableExists(conn, gbSeqTable);
char *seqTbl = haveGbSeq ? gbSeqTable : "seq";
char *version = NULL;
struct trackDb *tdbRgdEst;
char *chrom = cartString(cart, "c");
int start = cartInt(cart, "o");
int end = cartUsualInt(cart, "t",0);
struct gbWarn *gbWarn = checkGbWarn(conn, acc);
/* This sort of query and having to keep things in sync between
* the first clause of the select, the from clause, the where
* clause, and the results in the row ... is really tedious.
* One of my main motivations for going to a more object
* based rather than pure relational approach in general,
* and writing 'autoSql' to help support this. However
* the pure relational approach wins for pure search speed,
* and these RNA fields are searched. So it looks like
* the code below stays. Be really careful when you modify
* it.
*
* Uses the gbSeq table if available, otherwise use seq for older databases.
*/
sqlDyStringPrintf(dy,
"select g.type,g.direction,"
"so.name,o.name,l.name,m.name,"
"se.name,t.name,dev.name,ce.name,cd.name,"
"des.name,a.name,gene.name,p.name,"
"gbS.size,g.moddate,gbS.gbExtFile,gbS.file_offset,gbS.file_size ");
/* If the gbCdnaInfoTAble table has a "version" column then will show it */
if (hasVersion)
{
sqlDyStringPrintf(dy,
", g.version ");
}
sqlDyStringPrintf(dy,
" from %s g,%s gbS,%s so,%s o,%s l,%s m,%s se,%s t,"
"%s dev,%s ce,%s cd,%s des,%s a,%s gene,%s p"
" where g.acc = '%s' and g.id = gbS.id ",
gbCdnaInfoTable,seqTbl, sourceTable, organismTable, libraryTable, mrnaCloneTable, sexTable, tissueTable, developmentTable, cellTable, cdsTable, descriptionTable, authorTable, geneNameTable, productNameTable, acc);
sqlDyStringPrintf(dy,
"and g.source = so.id and g.organism = o.id "
"and g.library = l.id and g.mrnaClone = m.id "
"and g.sex = se.id and g.tissue = t.id "
"and g.development = dev.id and g.cell = ce.id "
"and g.cds = cd.id and g.description = des.id "
"and g.author = a.id and g.geneName = gene.id "
"and g.productName = p.id");
sr = sqlMustGetResult(conn, dy->string);
row = sqlNextRow(sr);
if (row != NULL)
{
type=row[0];direction=row[1];
// source=row[2]; unused variable
orgFullName=row[3];library=row[4];clone=row[5];
sex=row[6];tissue=row[7];development=row[8];cell=row[9];cds=row[10];description=row[11];
author=row[12];geneName=row[13];productName=row[14];
// seqSize = sqlUnsigned(row[15]); unused variable
date = row[16];
// ext_file = row[17]; unused variable
// fileOffset=sqlUnsigned(row[18]); unused variable
// fileSize=sqlUnsigned(row[19]); unused variable
boolean isEst = sameWord(type, "est");
if (hasVersion)
{
version = row[20];
}
/* Now we have all the info out of the database and into nicely named
* local variables. There's still a few hoops to jump through to
* format this prettily on the web with hyperlinks to NCBI. */
printf("Information on %s %s
\n", acc);
printf("Description: %s
\n", description);
if (gbWarn != NULL)
printGbWarn(acc, gbWarn);
medlineLinkedLine("Gene", geneName, geneName);
medlineProductLinkedLine("Product", productName);
dyStringClear(dy);
gbToEntrezAuthor(author, dy);
medlineLinkedLine("Author", author, dy->string);
printf("Organism: ");
printf("",
cgiEncode(orgFullName));
printf("%s
\n", orgFullName);
printf("Tissue: %s
\n", tissue);
printf("Development stage: %s
\n", development);
printf("Cell line: %s
\n", cell);
printf("Sex: %s
\n", sex);
printf("Library: %s
\n", library);
printf("Clone: %s
\n", clone);
if (isEst)
{
printf("Read direction: ");
if (direction[0] != '0')
printf("%s' (guessed from GenBank description)
\n", direction);
else
printf("unknown (can't guess from GenBank description)
");
}
else
printf("CDS: %s
\n", cds);
printf("Date: %s
\n", date);
if (hasVersion)
{
printf("Version: %s
\n", version);
}
/* print RGD EST Report link if it is Rat genome and it has a link to RGD */
if (sameWord(organism, "Rat"))
{
if (hTableExists(database, "rgdEstLink"))
{
sqlSafef(query, sizeof(query),
"select id from %s.rgdEstLink where name = '%s';", database, acc);
if (sqlQuickQuery(conn2, query, rgdEstId, sizeof(rgdEstId)) != NULL)
{
tdbRgdEst = hashFindVal(trackHash, "rgdEst");
printf("RGD EST Report: ");
printf("", tdbRgdEst->url, rgdEstId);
printf("RGD:%s
\n", rgdEstId);
}
}
}
if (isEst && hTableExists(database, "estOrientInfo") && (psl != NULL))
{
int estOrient = getEstTranscriptionDir(conn2, psl);
if (estOrient != 0)
printf("EST transcribed from %c strand (supported by %d splice sites).
\n",
(estOrient > 0 ? '+' : '-' ), abs(estOrient));
}
if (hGenBankHaveSeq(database, acc, NULL))
{
printf("%s sequence: ", type);
hgcAnchorSomewhere("htcDisplayMrna", acc, tdb->track, seqName);
printf("%s
\n", acc);
}
}
else
{
warn("Couldn't find %s in %s table", gbCdnaInfoTable, acc);
}
if (end != 0 && differentString(chrom,"0") && isNotEmpty(chrom))
{
printf("Position: "
"",
hgTracksPathAndSettings(), database, chrom, start+1, end);
printf("%s:%d-%d
\n", chrom, start+1, end);
}
gbWarnFree(&gbWarn);
sqlFreeResult(&sr);
dyStringFree(&dy);
hFreeConn(&conn);
hFreeConn(&conn2);
}
static boolean isPslToPrintByClick(struct psl *psl, int startFirst, boolean isClicked)
/* Determine if a psl should be printed based on if it was or was not the one that was clicked
* on.
*/
{
return ((psl->tStart == startFirst) && sameString(psl->tName, seqName)) == isClicked;
}
void printAlignmentsSimple(struct psl *pslList, int startFirst, char *hgcCommand,
char *tableName, char *itemIn)
/* Print list of mRNA alignments, don't add extra textual link when
* doesn't honor hgcCommand. */
{
struct psl *psl;
int aliCount = slCount(pslList);
boolean isClicked;
if (pslList == NULL || tableName == NULL)
return;
boolean showEvery = (strstr(itemIn, "PrintAllSequences") > 0);
if (!showEvery && (aliCount > 1))
printf("The alignment you clicked on is first in the table below.
\n");
printf("");
if (startsWith("chr", pslList->tName))
printf("BROWSER | SIZE IDENTITY CHROMOSOME STRAND START END QUERY START END TOTAL\n");
else
printf("BROWSER | SIZE IDENTITY SCAFFOLD STRAND START END QUERY START END TOTAL\n");
printf("-----------------------------------------------------------------------------------------------------\n");
for (isClicked = 1; isClicked >= 0; isClicked -= 1)
{
for (psl = pslList; psl != NULL; psl = psl->next)
{
if (isPslToPrintByClick(psl, startFirst, isClicked))
{
char otherString[512];
char *qName = itemIn;
if (showEvery)
qName = replaceChars(itemIn, "PrintAllSequences", psl->qName);
safef(otherString, sizeof(otherString), "%d&aliTable=%s", psl->tStart, tableName);
printf("browser | ",
hgTracksPathAndSettings(), database, psl->tName, psl->tStart+1, psl->tEnd);
if (psl->qSize <= MAX_DISPLAY_QUERY_SEQ_SIZE) // Only anchor if small enough
hgcAnchorWindow(hgcCommand, qName, psl->tStart, psl->tEnd, otherString, psl->tName);
char *displayChromName = chromAliasGetDisplayChrom(database, cart, psl->tName);
printf("%5d %5.1f%% %9s %s %9d %9d %20s %5d %5d %5d",
psl->match + psl->misMatch + psl->repMatch,
100.0 - pslCalcMilliBad(psl, TRUE) * 0.1,
skipChr(displayChromName), psl->strand, psl->tStart + 1, psl->tEnd,
psl->qName, psl->qStart+1, psl->qEnd, psl->qSize);
if (psl->qSize <= MAX_DISPLAY_QUERY_SEQ_SIZE)
printf("");
printf("\n");
if (showEvery)
freeMem(qName);
}
}
}
printf("");
}
void printAlignmentsExtra(struct psl *pslList, int startFirst, char *hgcCommand, char *hgcCommandInWindow,
char *tableName, char *itemIn)
/* Print list of mRNA alignments with special "in window" alignment function. */
{
if (pslList == NULL || tableName == NULL)
return;
printAlignmentsSimple(pslList, startFirst, hgcCommand, tableName, itemIn);
struct psl *psl = pslList;
for (psl = pslList; psl != NULL; psl = psl->next)
{
if ( pslTrimToTargetRange(psl, winStart, winEnd) != NULL
&&
!startsWith("xeno", tableName)
&& !(startsWith("user", tableName) && pslIsProtein(psl))
&& psl->tStart == startFirst
&& sameString(psl->tName, seqName)
)
{
boolean showEvery = (strstr(itemIn, "PrintAllSequences") > 0);
char *qName = itemIn;
if (showEvery)
qName = replaceChars(itemIn, "PrintAllSequences", psl->qName);
char otherString[512];
safef(otherString, sizeof(otherString), "%d&aliTable=%s",
psl->tStart, tableName);
hgcAnchorSomewhere(hgcCommandInWindow, qName, otherString, psl->tName);
printf("
View details of parts of alignment within browser window.
\n");
}
}
}
void printAlignments(struct psl *pslList, int startFirst, char *hgcCommand,
char *tableName, char *itemIn)
/* Print list of mRNA alignments. */
{
printAlignmentsExtra(pslList, startFirst, hgcCommand, "htcCdnaAliInWindow", tableName, itemIn);
}
static struct psl *getAlignmentsTName(struct sqlConnection *conn, char *table, char *acc,
char *tName)
/* get the list of alignments for the specified acc and tName (if given). */
{
struct sqlResult *sr = NULL;
char **row;
struct psl *psl, *pslList = NULL;
boolean hasBin;
char splitTable[HDB_MAX_TABLE_STRING];
char query[1024];
// Use the conn's db rather than the global `database`; for quickLifted
// tracks the conn is on the source assembly while `database` is the
// destination (possibly hub_NNN_).
char *connDb = sqlGetDatabase(conn);
if (!hFindSplitTable(connDb, seqName, table, splitTable, sizeof splitTable, &hasBin))
errAbort("can't find table %s or %s_%s", table, seqName, table);
if (isNotEmpty(tName))
sqlSafef(query, sizeof(query), "select * from %s where qName = '%s' and tName = '%s'",
splitTable, acc, tName);
else
sqlSafef(query, sizeof(query), "select * from %s where qName = '%s'", splitTable, acc);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
psl = pslLoad(row+hasBin);
slAddHead(&pslList, psl);
}
sqlFreeResult(&sr);
slReverse(&pslList);
return pslList;
}
struct psl *getAlignments(struct sqlConnection *conn, char *table, char *acc)
/* get the list of alignments for the specified acc */
{
return getAlignmentsTName(conn, table, acc, NULL);
}
struct psl *loadPslRangeT(char *table, char *qName, char *tName, int tStart, int tEnd)
/* Load a list of psls given qName tName tStart tEnd */
{
struct sqlResult *sr = NULL;
char **row;
struct psl *psl = NULL, *pslList = NULL;
boolean hasBin;
char splitTable[HDB_MAX_TABLE_STRING];
char query[256];
struct sqlConnection *conn = hAllocConn(database);
if (!hFindSplitTable(database, seqName, table, splitTable, sizeof splitTable, &hasBin))
errAbort("loadPslRangeT track %s not found", table);
sqlSafef(query, sizeof(query), "select * from %s where qName = '%s' and tName = '%s' and tEnd > %d and tStart < %d", splitTable, qName, tName, tStart, tEnd);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
psl = pslLoad(row+hasBin);
slAddHead(&pslList, psl);
}
sqlFreeResult(&sr);
slReverse(&pslList);
hFreeConn(&conn);
return pslList;
}
void doHgRna(struct trackDb *tdb, char *acc)
/* Click on an individual RNA. */
{
char *track = tdb->track;
char *table = tdb->table;
struct sqlConnection *conn = hAllocConn(database);
char *type;
int start = cartInt(cart, "o");
struct psl *pslList = NULL;
if (sameString("xenoMrna", track) || sameString("xenoBestMrna", track) || sameString("xenoEst", track) || sameString("sim4", track) )
{
char temp[256];
safef(temp, sizeof temp, "non-%s RNA", organism);
type = temp;
}
else if ( sameWord("blatzHg17KG", track) )
{
type = "Human mRNA";
}
else if (stringIn("estFiltered",track))
{
type = "EST";
}
else if (stringIn("est", track) || stringIn("Est", track))
{
type = "EST";
// table = "all_est"; // Should fall out of wash now
}
else if (startsWith("psu", track))
{
type = "Pseudo & Real Genes";
table = "psu";
}
else if (sameWord("xenoBlastzMrna", track) )
{
type = "Blastz to foreign mRNA";
}
else if (startsWith("mrnaBlastz",track ))
{
type = "mRNA";
}
else if (startsWith("pseudoMrna",track) || startsWith("pseudoGeneLink",track))
{
type = "mRNA";
table = "pseudoMrna";
}
else if (startsWith("celeraMrna",track))
{
type = "mRNA";
}
else if (startsWith("all_mrnaFiltered",track))
{
type = "mRNA";
}
else
{
type = "mRNA";
// table = "all_mrna"; // should fall out of wash now
}
/* Print non-sequence info. */
cartWebStart(cart, database, "%s", acc);
printRnaSpecs(tdb, acc, pslList);
/* Get alignment info. */
pslList = getAlignments(conn, table, acc);
if (pslList == NULL)
{
/* this was not actually a click on an aligned item -- we just
* want to display RNA info, so leave here */
hFreeConn(&conn);
htmlHorizontalLine();
printf("mRNA %s alignment does not meet minimum alignment criteria on this assembly.", acc);
return;
}
htmlHorizontalLine();
printf("%s/Genomic Alignments
", type);
if (startsWith("mrnaBlastz",tdb->table))
slSort(&pslList, pslCmpScoreDesc);
printAlignments(pslList, start, "htcCdnaAli", table, acc);
printTrackHtml(tdb);
hFreeConn(&conn);
}
void printPslFormat(struct sqlConnection *conn, struct trackDb *tdb, char *item, int start,
char *subType)
/* Handles click in affyU95 or affyU133 tracks */
{
struct psl *pslList = getAlignments(conn, tdb->table, item);
struct psl *psl;
char *face = "Times"; /* specifies font face to use */
char *fsize = "+1"; /* specifies font size */
/* check if there is an alignment available for this sequence. This checks
* both genbank sequences and other sequences in the seq table. If so,
* set it up so they can click through to the alignment. */
if (hGenBankHaveSeq(database, item, NULL))
{
printf("%s/Genomic Alignments
", item);
printAlignments(pslList, start, "htcCdnaAli", tdb->table, item);
}
else
{
/* print out the psls */
printf("");
printf("\n", face, fsize);
for (psl = pslList; psl != NULL; psl = psl->next)
{
pslOutFormat(psl, stdout, '\n', '\n');
}
printf("\n");
}
pslFreeList(&pslList);
}
void doAffy(struct trackDb *tdb, char *item, char *itemForUrl)
/* Display information for Affy tracks*/
{
char *dupe, *type, *words[16];
char *orthoTable = trackDbSetting(tdb, "orthoTable");
char *otherDb = trackDbSetting(tdb, "otherDb");
int wordCount;
int start = cartInt(cart, "o");
char query[256];
char **row;
struct sqlResult *sr = NULL;
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2 = hAllocConn(database);
if (itemForUrl == NULL)
itemForUrl = item;
dupe = cloneString(tdb->type);
genericHeader(tdb, item);
wordCount = chopLine(dupe, words);
printCustomUrl(tdb, itemForUrl, item == itemForUrl);
/* If this is the affyZebrafish track, check for human ortholog information */
if (sameString("affyZebrafish", tdb->table))
{
if (orthoTable != NULL && hTableExists(database, orthoTable))
{
sqlSafef(query, sizeof(query), "select geneSymbol, description from %s where name = '%s' ", orthoTable, item);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
{
printf("
\n\n");
printf("Human %s Ortholog:
%s \n", otherDb, row[0]);
printf("Ortholog Description: %s \n",row[1]);
printf("
\n");
}
}
}
if (wordCount > 0)
{
type = words[0];
if (sameString(type, "psl"))
{
char *subType = ".";
if (wordCount > 1)
subType = words[1];
printPslFormat(conn2, tdb, item, start, subType);
}
}
printTrackHtml(tdb);
freez(&dupe);
hFreeConn(&conn);
hFreeConn(&conn2);
}
void doZfishRHmap(struct trackDb *tdb, char *itemName)
/* Put up Radiation Hybrid map information for Zebrafish */
{
char *dupe, *type, *words[16];
char query[256];
struct sqlResult *sr = NULL;
char **row = NULL;
struct rhMapZfishInfo *rhInfo = NULL;
int wordCount;
int start = cartInt(cart, "o");
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn1 = hAllocConn(database);
boolean rhMapInfoExists = sqlTableExists(conn, "rhMapZfishInfo");
dupe = cloneString(tdb->type);
wordCount = chopLine(dupe, words);
genericHeader(tdb, itemName);
/* Print out RH map information if available */
if (rhMapInfoExists)
{
sqlSafef(query, sizeof query, "SELECT * FROM rhMapZfishInfo WHERE name = '%s'", itemName);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row != NULL)
{
rhInfo = rhMapZfishInfoLoad(row);
if (rhInfo != NULL)
{
printf("Information on %s
\n", itemName);
if (!sameString(rhInfo->zfinId, ""))
{
printf("");
printCustomUrl(tdb, rhInfo->zfinId, TRUE);
printf("
\n");
}
printf("
\n\n");
printf("Linkage group: %s \n", rhInfo->linkageGp);
printf("Position on linkage group: %d \n", rhInfo->position);
printf("Distance (cR): %d \n", rhInfo->distance);
printf("Marker type: %s \n", rhInfo->markerType);
printf("Marker source: %s \n", rhInfo->source);
printf("Mapping institution: %s \n", rhInfo->mapSite);
printf("Forward Primer: %s \n", rhInfo->leftPrimer);
printf("Reverse Primer: %s \n", rhInfo->rightPrimer);
printf("
\n");
}
}
}
dupe = cloneString(tdb->type);
wordCount = chopLine(dupe, words);
if (wordCount > 0)
{
type = words[0];
if (sameString(type, "psl"))
{
char *subType = ".";
if (wordCount > 1)
subType = words[1];
printPslFormat(conn1, tdb, itemName, start, subType);
}
}
printTrackHtml(tdb);
freez(&dupe);
hFreeConn(&conn);
hFreeConn(&conn1);
}
void doRikenRna(struct trackDb *tdb, char *item)
/* Put up Riken RNA stuff. */
{
char query[512];
struct sqlResult *sr;
char **row;
struct sqlConnection *conn = sqlConnect("mgsc");
genericHeader(tdb, item);
sqlSafef(query, sizeof query, "select * from rikenMrna where qName = '%s'", item);
sr = sqlGetResult(conn, query);
printf("\n");
printf("#match\tmisMatches\trepMatches\tnCount\tqNumInsert\tqBaseInsert\ttNumInsert\tBaseInsert\tstrand\tqName\tqSize\tqStart\tqEnd\ttName\ttSize\ttStart\ttEnd\tblockCount\tblockSizes\tqStarts\ttStarts\n");
while ((row = sqlNextRow(sr)) != NULL)
{
struct psl *psl = pslLoad(row+1);
pslTabOut(psl, stdout);
}
printf("\n");
sqlDisconnect(&conn);
printTrackHtml(tdb);
}
void doYaleTars(struct trackDb *tdb, char *item, char *itemForUrl)
/* Display information for Affy tracks*/
{
char *dupe, *type, *words[16], *chrom = NULL, *strand = NULL;
char *item2 = NULL;
int wordCount, end = 0;
int start = cartInt(cart, "o");
char query[256];
char **row;
struct sqlResult *sr = NULL;
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2 = hAllocConn(database);
if (itemForUrl == NULL)
{
if (startsWith("TAR", item))
{
/* Remove TAR prefix from item */
item2 = strchr(item, 'R');
item2++;
itemForUrl = item2;
}
else
itemForUrl = item;
}
dupe = cloneString(tdb->type);
genericHeader(tdb, item);
wordCount = chopLine(dupe, words);
printCustomUrl(tdb, itemForUrl, item == itemForUrl);
sqlSafef(query, sizeof(query), "select tName, tEnd, strand from %s where qName='%s' and tStart=%d;", tdb->table, item, start);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
/* load PSL into struct */
if (row != NULL)
{
chrom = cloneString(row[0]);
end = sqlUnsigned(row[1]);
strand = cloneString(row[2]);
}
printPos(chrom, start, end, strand, TRUE, item);
if (wordCount > 0)
{
type = words[0];
if (sameString(type, "psl"))
{
char *subType = ".";
if (wordCount > 1)
subType = words[1];
printPslFormat(conn2, tdb, item, start, subType);
}
}
printTrackHtml(tdb);
freez(&dupe);
hFreeConn(&conn);
hFreeConn(&conn2);
}
void printPcrTargetMatch(struct targetDb *target, struct psl *tpsl,
boolean mustGetItem)
/* Show the non-genomic target PCR result and its genomic mapping. */
{
char *acc = pcrResultItemAccession(tpsl->tName);
char *name = pcrResultItemName(tpsl->tName);
char niceName[256];
if (name == NULL || sameString(acc, name))
safecpy(niceName, sizeof(niceName), acc);
else
safef(niceName, sizeof(niceName), "%s (%s)", name, acc);
printf("Position in %s: %s"
":%d-%d
\n",
target->description, hgTracksName(), cartSidUrlString(cart), database,
acc, niceName, tpsl->tStart+1, tpsl->tEnd);
printf("Size in %s: %d
\n", niceName,
tpsl->tEnd - tpsl->tStart);
if (tpsl->strand[0] == '-')
printf(" "
"Warning: the match is on the reverse strand of %s
\n",
niceName);
struct psl *itemPsl = NULL, *otherPsls = NULL, *gpsl;
int itemStart = cartInt(cart, "o");
int itemEnd = cartInt(cart, "t");
int rowOffset = hOffsetPastBin(database, seqName, target->pslTable);
struct sqlConnection *conn = hAllocConn(database);
struct sqlResult *sr;
char **row;
char query[2048];
sqlSafef(query, sizeof(query), "select * from %s where qName = '%s'",
target->pslTable, acc);
sr = sqlGetResult(conn, query);
while ((row = sqlNextRow(sr)) != NULL)
{
gpsl = pslLoad(row+rowOffset);
struct psl *pslTrimmed = pslTrimToQueryRange(gpsl, tpsl->tStart,
tpsl->tEnd);
if (sameString(gpsl->tName, seqName) &&
((gpsl->tStart == itemStart && gpsl->tEnd == itemEnd) ||
(pslTrimmed->tStart == itemStart && pslTrimmed->tEnd == itemEnd)))
itemPsl = pslTrimmed;
else
slAddHead(&otherPsls, pslTrimmed);
pslFree(&gpsl);
}
hFreeConn(&conn);
if (mustGetItem && itemPsl == NULL)
errAbort("Did not find record for amplicon in %s at %s:%d-%d",
niceName, seqName, itemStart, itemEnd);
char strand[2];
strand[1] = '\0';
if (itemPsl != NULL)
{
if (itemPsl->strand[1] == '\0')
strand[0] = itemPsl->strand[0];
else if (itemPsl->strand[0] != itemPsl->strand[1])
strand[0] = '-';
else
strand[0] = '+';
if (itemPsl != NULL)
printPosOnChrom(itemPsl->tName, itemPsl->tStart, itemPsl->tEnd,
strand, FALSE, tpsl->tName);
}
slSort(&otherPsls, pslCmpTarget);
if (itemPsl != NULL && otherPsls != NULL)
printf("Other matches in genomic alignments of %s:
\n",
niceName);
for (gpsl = otherPsls; gpsl != NULL; gpsl = gpsl->next)
{
if (gpsl->strand[1] == '\0')
strand[0] = gpsl->strand[0];
else if (gpsl->strand[0] != gpsl->strand[1])
strand[0] = '-';
else
strand[0] = '+';
printPosOnChrom(gpsl->tName, gpsl->tStart, gpsl->tEnd, strand, FALSE,
tpsl->tName);
}
pslFree(&itemPsl);
pslFreeList(&otherPsls);
}
static void upperMatch(char *dna, char *primer, int size)
/* Uppercase DNA where it matches primer. -- copied from gfPcrLib.c. */
{
int i;
for (i=0; itEnd - psl->tStart;
char *ffPrimer = cloneString(fPrimer);
char *rrPrimer = cloneString(rPrimer);
int rPrimerSize = strlen(rPrimer);
struct dnaSeq *seq;
if (stringIn("__", item) && target != NULL)
{
/* Use seq+extFile if specified; otherwise just retrieve from seqFile. */
if (isNotEmpty(target->seqTable) && isNotEmpty(target->extFileTable))
{
struct sqlConnection *conn = hAllocConn(database);
seq = hDnaSeqGet(database, psl->tName, target->seqTable,
target->extFileTable);
hFreeConn(&conn);
char *dna = cloneStringZ(seq->dna + psl->tStart, productSize);
freeMem(seq->dna);
seq->dna = dna;
}
else
{
struct twoBitFile *tbf = twoBitOpen(target->seqFile);
seq = twoBitReadSeqFrag(tbf, psl->tName, psl->tStart,
psl->tEnd);
twoBitClose(&tbf);
}
}
else
seq = hChromSeq(database, psl->tName, psl->tStart, psl->tEnd);
char *dna = seq->dna;
tolowers(dna);
if (psl->strand[0] == '-')
reverseComplement(dna, productSize);
printf("");
/* The rest of this is loosely copied from gfPcrLib.c:outputFa(): */
char *tNameForPos = (target != NULL ? pcrResultItemAccession(psl->tName) : psl->tName);
printf(">tStart+1, psl->tEnd);
printf("\">%s:%d%c%d %dbp %s %s\n",
psl->tName, psl->tStart+1, psl->strand[0], psl->tEnd,
productSize, fPrimer, rPrimer);
/* Flip reverse primer to be in same direction and case as sequence, to
* compare with sequence: */
reverseComplement(rrPrimer, rPrimerSize);
tolowers(rrPrimer);
tolowers(ffPrimer);
/* Capitalize where sequence and primer match, and write out sequence. */
upperMatch(dna, ffPrimer, strlen(ffPrimer));
upperMatch(dna + productSize - rPrimerSize, rrPrimer, rPrimerSize);
faWriteNext(stdout, NULL, dna, productSize);
printf("");
}
static void pslFileGetPrimers(char *pslFileName, char *transcript, int ampStart, int ampEnd,
char **retFPrimer, char **retRPrimer)
/* Use a psl file to get primers associated with the transcript */
{
char *pslFields[21];
struct lineFile *lf = lineFileOpen(pslFileName, TRUE);
char *target = cloneString(transcript);
char *pipe = strchr(target, '|');
*pipe = '\0';
while (lineFileRow(lf, pslFields))
{
struct psl *psl = pslLoad(pslFields);
if (sameString(psl->tName, target) && ampStart == psl->tStart && ampEnd == psl->tEnd)
{
char *pair = psl->qName;
char *under = strchr(pair, '_');
*under = '\0';
*retFPrimer = cloneString(pair);
*retRPrimer = cloneString(under+1);
break;
}
}
lineFileClose(&lf);
}
void doPcrResult(char *track, char *item)
/* Process click on PCR of user's primers. */
{
struct trackDb *tdb = pcrResultFakeTdb();
char *pslFileName, *primerFileName;
struct targetDb *target;
cartWebStart(cart, database, "PCR Results");
if (! pcrResultParseCart(database, cart, &pslFileName, &primerFileName, &target))
errAbort("PCR Result track has disappeared!");
char *fPrimer = NULL, *rPrimer = NULL;
int ampStart, ampEnd;
char *targetSeqName = NULL;
boolean targetSearch = stringIn("__", item) != NULL;
if (targetSearch)
{
/* item (from hgTracks) is |-separated: target sequence name,
* amplicon start offset in target sequence, and amplicon end offset. */
char *words[3];
int wordCount = chopByChar(cloneString(item), '|', words, ArraySize(words));
if (wordCount != 3)
errAbort("doPcrResult: expected 3 |-sep'd words but got '%s'", item);
targetSeqName = words[0];
if (endsWith(targetSeqName, "__"))
targetSeqName[strlen(targetSeqName)-2] = '\0';
ampStart = atoi(words[1]), ampEnd = atoi(words[2]);
// use the psl file to find the right primer pair
pslFileGetPrimers(pslFileName, item, ampStart, ampEnd, &fPrimer, &rPrimer);
}
else if (stringIn("_", item))
{
// the item name contains the forward and reverse primers
int maxSplits = 2;
char *splitQName[maxSplits];
int numSplits = chopString(cloneString(item), "_", splitQName, sizeof(splitQName));
if (numSplits == maxSplits)
{
fPrimer = splitQName[0];
touppers(fPrimer);
rPrimer = splitQName[1];
touppers(rPrimer);
}
}
else
{
pcrResultGetPrimers(primerFileName, &fPrimer, &rPrimer, NULL);
}
printf("PCR Results (%s %s)
\n", fPrimer, rPrimer);
printf("Forward primer: 5' %s 3'
\n", fPrimer);
printf("Reverse primer: 5' %s 3'
\n", rPrimer);
if (targetSearch)
printf("Search target: %s
\n", target->description);
struct psl *itemPsl = NULL, *otherPsls = NULL, *psl;
if (targetSearch)
{
pcrResultGetPsl(pslFileName, target, targetSeqName, seqName, ampStart, ampEnd,
&itemPsl, &otherPsls, fPrimer, rPrimer);
printPcrTargetMatch(target, itemPsl, TRUE);
}
else
{
pcrResultGetPsl(pslFileName, NULL, item,
seqName, cartInt(cart, "o"), cartInt(cart, "t"),
&itemPsl, &otherPsls, fPrimer, rPrimer);
printPosOnChrom(itemPsl->tName, itemPsl->tStart, itemPsl->tEnd,
itemPsl->strand, FALSE, NULL);
}
if (otherPsls != NULL)
{
puts("
");
printf("Other matches for these primers:
\n");
for (psl = otherPsls; psl != NULL; psl = psl->next)
{
puts("
");
if (stringIn("__", psl->tName))
printPcrTargetMatch(target, psl, FALSE);
else
printPosOnChrom(psl->tName, psl->tStart, psl->tEnd,
psl->strand, FALSE, NULL);
}
puts("
");
}
printPcrSequence(item, target, itemPsl, fPrimer, rPrimer);
puts("
");
printTrackHtml(tdb);
}
void doUserPsl(char *track, char *item)
/* Process click on user-defined alignment. */
{
int start = cartInt(cart, "o");
struct lineFile *lf;
struct psl *pslList = NULL, *psl;
char *pslName, *faName, *qName;
enum gfType qt, tt;
boolean isProt;
cartWebStart(cart, database, "BLAT Search Alignments");
printf("BLAT Search Alignments
\n");
printf("Show All\n");
printf("Click on a line to see detailed letter-by-letter display
\n");
printf("\n");
parseSs(item, &pslName, &faName, &qName);
pslxFileOpen(pslName, &qt, &tt, &lf);
while ((psl = pslNext(lf)) != NULL)
{
if (sameString(psl->qName, qName))
{
slAddHead(&pslList, psl);
}
else
{
pslFree(&psl);
}
}
slSort(&pslList, pslCmpQueryScore);
lineFileClose(&lf);
printAlignments(pslList, start, "htcUserAli", "user", item);
pslFreeList(&pslList);
printf("\n");
printf("\n");
jsInline("$('#hgUsualPslShowAllLink').click(function(){\n"
" $('#hgUsualPslShowItem')[0].style.display = 'none';\n"
" $('#hgUsualPslShowAll')[0].style.display = 'block';\n"
" $('#hgUsualPslShowAllLink')[0].style.display = 'none';\n"
"return false;\n"
"});\n");
webIncludeHelpFile(USER_PSL_TRACK_NAME, TRUE);
}
void doHgGold(struct trackDb *tdb, char *fragName)
/* Click on a fragment of golden path. */
{
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2 = hAllocConn(database);
struct sqlConnection *conn3 = hAllocConn(database);
char query[256];
struct sqlResult *sr;
char **row;
char query2[256];
struct sqlResult *sr2;
char **row2;
char query3[256];
struct sqlResult *sr3;
char **row3;
struct agpFrag frag;
struct contigAcc contigAcc;
int start = cartInt(cart, "o");
boolean hasBin;
char splitTable[HDB_MAX_TABLE_STRING];
char *chp;
char *accession1, *accession2, *spanner, *variation, *varEvidence,
*contact, *remark, *comment;
// char *evaluation; unused variable
char *secondAcc, *secondAccVer;
char *tmpString;
int first;
cartWebStart(cart, database, "%s", fragName);
if (!hFindSplitTable(database, seqName, tdb->table, splitTable, sizeof splitTable, &hasBin))
errAbort("doHgGold track %s not found", tdb->table);
sqlSafef(query, sizeof query, "select * from %s where frag = '%s' and chromStart = %d",
splitTable, fragName, start);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
agpFragStaticLoad(row+hasBin, &frag);
printf("Entrez nucleotide: %s
\n", fragName, fragName);
printf("Clone Fragment ID: %s
\n", frag.frag);
printf("Clone Fragment Type: %s
\n", frag.type);
printf("Clone Bases: %d-%d
\n", frag.fragStart+1, frag.fragEnd);
if (hTableExists(database, "contigAcc"))
{
sqlSafef(query2, sizeof query2, "select * from contigAcc where contig = '%s'", frag.frag);
if ((sr2 = sqlGetResult(conn2, query2)))
{
row = sqlNextRow(sr2);
if (row)
{
contigAccStaticLoad(row, &contigAcc);
printf("Genbank Accession: %s
\n", contigAcc.acc);
}
sqlFreeResult(&sr2);
}
}
printPos(frag.chrom, frag.chromStart, frag.chromEnd, frag.strand, FALSE, NULL);
if (hTableExists(database, "certificate"))
{
first = 1;
again:
tmpString = cloneString(frag.frag);
chp = strstr(tmpString, ".");
if (chp != NULL) *chp = '\0';
if (first)
{
sqlSafef(query2, sizeof query2, "select * from certificate where accession1='%s';", tmpString);
}
else
{
sqlSafef(query2, sizeof query2, "select * from certificate where accession2='%s';", tmpString);
}
sr2 = sqlMustGetResult(conn2, query2);
row2 = sqlNextRow(sr2);
while (row2 != NULL)
{
printf("
");
accession1 = row2[0];
accession2 = row2[1];
spanner = row2[2];
// evaluation = row2[3]; unused variable
variation = row2[4];
varEvidence = row2[5];
contact = row2[6];
remark = row2[7];
comment = row2[8];
if (first)
{
secondAcc = accession2;
}
else
{
secondAcc = accession1;
}
sqlSafef(query3, sizeof query3, "select frag from %s where frag like '%s.%c';",
splitTable, secondAcc, '%');
sr3 = sqlMustGetResult(conn3, query3);
row3 = sqlNextRow(sr3);
if (row3 != NULL)
{
secondAccVer = row3[0];
}
else
{
secondAccVer = secondAcc;
}
printf("Non-standard Join Certificate:
\n");
printf("The join between %s and %s is not standard due to a ", frag.frag, secondAccVer);
printf("sub-optimal sequence alignment between the overlapping regions of the ");
printf("clones. The following details are provided by the ");
printf("sequencing center to support the joining of these two clones:
");
printf("Joined with Fragment: %s
\n", secondAccVer);
if (strcmp(spanner, "") != 0) printf("Spanner: %s
\n", spanner);
/* if (strcmp(evaluation, "") != 0) printf("Evaluation: %s
\n", evaluation); */
if (strcmp(variation, "") != 0) printf("Variation: %s
\n", variation);
if (strcmp(varEvidence, "")!= 0) printf("Variation Evidence: %s
\n", varEvidence);
if (strcmp(remark, "") != 0) printf("Remark: %s
\n", remark);
if (strcmp(comment, "") != 0) printf("Comment: %s
\n", comment);
if (strcmp(contact, "") != 0)
printf("Contact: %s
", contact, contact);
sqlFreeResult(&sr3);
row2 = sqlNextRow(sr2);
}
sqlFreeResult(&sr2);
if (first)
{
first = 0;
goto again;
}
}
sqlFreeResult(&sr);
hFreeConn(&conn);
hFreeConn(&conn2);
hFreeConn(&conn3);
printTrackHtml(tdb);
}
void doHgGap(struct trackDb *tdb, char *gapType)
/* Print a teeny bit of info about a gap. */
{
struct sqlConnection *conn = hAllocConn(database);
char query[256];
struct sqlResult *sr;
char **row;
struct agpGap gap;
int start = cartInt(cart, "o");
boolean hasBin;
char splitTable[HDB_MAX_TABLE_STRING];
cartWebStart(cart, database, "Gap in Sequence");
if (!hFindSplitTable(database, seqName, tdb->table, splitTable, sizeof splitTable, &hasBin))
errAbort("doHgGap track %s not found", tdb->table);
if (sameString(tdb->table, splitTable))
sqlSafef(query, sizeof(query), "select * from %s where chrom = '%s' and "
"chromStart = %d",
splitTable, seqName, start);
else
sqlSafef(query, sizeof(query), "select * from %s where chromStart = %d",
splitTable, start);
sr = sqlMustGetResult(conn, query);
row = sqlNextRow(sr);
if (row == NULL)
errAbort("Couldn't find gap at %s:%d", seqName, start);
agpGapStaticLoad(row+hasBin, &gap);
printf("Gap Type: %s
\n", gap.type);
printf("Bridged: %s
\n", gap.bridge);
printPos(gap.chrom, gap.chromStart, gap.chromEnd, NULL, FALSE, NULL);
printTrackHtml(tdb);
sqlFreeResult(&sr);
hFreeConn(&conn);
}
void selectOneRow(struct sqlConnection *conn, char *table, char *query,
struct sqlResult **retSr, char ***retRow)
/* Do query and return one row offset by bin as needed. */
{
char fullTable[HDB_MAX_TABLE_STRING];
boolean hasBin;
char **row;
if (!hFindSplitTable(database, seqName, table, fullTable, sizeof fullTable, &hasBin))
errAbort("Table %s doesn't exist in database", table);
*retSr = sqlGetResult(conn, query);
if ((row = sqlNextRow(*retSr)) == NULL)
errAbort("No match to query '%s'", query);
*retRow = row + hasBin;
}
void doHgContig(struct trackDb *tdb, char *ctgName)
/* Click on a contig. */
{
struct sqlConnection *conn = hAllocConn(database);
struct sqlConnection *conn2 = hAllocConn(database);
char query[256], query2[256], ctgUrl[256];
struct sqlResult *sr, *sr2;
char **row;
struct ctgPos *ctg;
struct ctgPos2 *ctg2 = NULL;
int cloneCount;
struct contigAcc contigAcc;
char *ncbiTerm = cgiEncode(ctgName);
safef(ctgUrl, sizeof(ctgUrl), "%s%s", NUCCORE_SEARCH, ncbiTerm);
genericHeader(tdb, ctgName);
char *url = tdb->url;
if (sameWord(database,"oryCun2"))
printf("Name: %s
\n", ctgName);
else if (isNotEmpty(url))
{
if (sameWord(url, "none"))
printf("Name: %s
\n", ctgName);
else
printCustomUrl(tdb, ctgName, TRUE);
}
else
printf("Name: %s
\n",
ctgUrl, ctgName);
freeMem(ncbiTerm);
sqlSafef(query, sizeof(query), "select * from %s where contig = '%s'",
tdb->table, ctgName);
selectOneRow(conn, tdb->table, query, &sr, &row);
if (sameString("ctgPos2", tdb->table))
{
ctg2 = ctgPos2Load(row);
printf("Type: %s
\n", ctg2->type);
ctg = (struct ctgPos*)ctg2;
}
else
ctg = ctgPosLoad(row);
sqlFreeResult(&sr);
if (hTableExists(database, "contigAcc"))
{
sqlSafef(query2, sizeof query2, "select * from contigAcc where contig = '%s'", ctgName);
if ((sr2 = sqlGetResult(conn2, query2)))
{
row = sqlNextRow(sr2);
if (row)
{
contigAccStaticLoad(row, &contigAcc);
printf("Genbank Accession: %s
\n", contigAcc.acc);
}
sqlFreeResult(&sr2);
}
}
if (hTableExists(database, "clonePos"))
{
sqlSafef(query, sizeof query, "select count(*) from clonePos"
" where chrom = '%s' and chromEnd >= %d and chromStart <= %d",
ctg->chrom, ctg->chromStart, ctg->chromEnd);
cloneCount = sqlQuickNum(conn, query);
printf("Total Clones: %d
\n", cloneCount);
}
printPos(ctg->chrom, ctg->chromStart, ctg->chromEnd, NULL, TRUE, ctg->contig);
printTrackHtml(tdb);
hFreeConn(&conn);
hFreeConn(&conn2);
}
char *cloneStageName(char *stage)
/* Expand P/D/F. */
{
switch (stage[0])
{
case 'P':
return "predraft (less than 4x coverage shotgun)";
case 'D':
return "draft (at least 4x coverage shotgun)";
case 'F':
return "finished";
default:
return "unknown";
}
}
void doHgCover(struct trackDb *tdb, char *cloneName)
/* Respond to click on clone. */
{
struct sqlConnection *conn = hAllocConn(database);
char query[256];
struct sqlResult *sr;
char **row;
struct clonePos *clone;
int fragCount;
cartWebStart(cart, database, "%s", cloneName);
sqlSafef(query, sizeof query, "select * from %s where name = '%s'", tdb->table, cloneName);
selectOneRow(conn, tdb->table, query, &sr, &row);
clone = clonePosLoad(row);
sqlFreeResult(&sr);
sqlSafef(query, sizeof query,
"select count(*) from %s_gl where end >= %d and start <= %d and frag like '%s%%'",
clone->chrom, clone->chromStart, clone->chromEnd, clone->name);
fragCount = sqlQuickNum(conn, query);
printf("Information on %s
\n", cloneName);
printf("GenBank: %s
\n", cloneName);
printf("Status: %s
\n", cloneStageName(clone->stage));
printf("Fragments: %d
\n", fragCount);
printf("Size: %d bases
\n", clone->seqSize);
printf("Chromosome: %s
\n", skipChr(clone->chrom));
printf("
\n");
hFreeConn(&conn);
printTrackHtml(tdb);
}
void doHgClone(struct trackDb *tdb, char *fragName)
/* Handle click on a clone. */
{
char cloneName[128];
fragToCloneVerName(fragName, cloneName);
doHgCover(tdb, cloneName);
}
void doBactigPos(struct trackDb *tdb, char *bactigName)
/* Click on a bactig. */
{
struct bactigPos *bactig;
struct sqlConnection *conn = hAllocConn(database);
struct sqlResult *sr;
char **row;
char query[256];
char goldTable[16];
char ctgStartStr[16];
int ctgStart;
genericHeader(tdb, bactigName);
sqlSafef(query, sizeof query, "select * from %s where name = '%s'", tdb->table, bactigName);
selectOneRow(conn, tdb->table, query, &sr, &row);
bactig = bactigPosLoad(row);
sqlFreeResult(&sr);
printf("Name: %s
\n", bactigName);
snprintf(goldTable, sizeof(goldTable), "%s_gold", seqName);
puts("First contig:");
if (hTableExists(database, goldTable))
{
sqlSafef(query, sizeof(query),
"select chromStart from %s where frag = \"%s\"",
goldTable, bactig->startContig);
ctgStart = sqlQuickNum(conn, query);
snprintf(ctgStartStr, sizeof(ctgStartStr), "%d", ctgStart);
hgcAnchor("gold", bactig->startContig, ctgStartStr);
}
printf("%s
\n", bactig->startContig);
puts("Last contig:");
if (hTableExists(database, goldTable))
{
sqlSafef(query, sizeof(query),
"select chromStart from %s where frag = \"%s\"",
goldTable, bactig->endContig);
ctgStart = sqlQuickNum(conn, query);
snprintf(ctgStartStr, sizeof(ctgStartStr), "%d", ctgStart);
hgcAnchor("gold", bactig->endContig, ctgStartStr);
}
printf("%s
\n", bactig->endContig);
printPos(bactig->chrom, bactig->chromStart, bactig->chromEnd, NULL, FALSE,NULL);
printTrackHtml(tdb);
hFreeConn(&conn);
}
int showGfAlignment(struct psl *psl, bioSeq *qSeq, FILE *f,
enum gfType qType, int qStart, int qEnd, char *qName)
/* Show protein/DNA alignment or translated DNA alignment. */
{
int blockCount;
int tStart = psl->tStart;
int tEnd = psl->tEnd;
char tName[256];
struct dnaSeq *tSeq;
/* protein psl's have a tEnd that isn't quite right */
if ((psl->strand[1] == '+') && (qType == gftProt))
tEnd = psl->tStarts[psl->blockCount - 1] + psl->blockSizes[psl->blockCount - 1] * 3;
tSeq = hDnaFromSeq(database, seqName, tStart, tEnd, dnaLower);
freez(&tSeq->name);
tSeq->name = cloneString(psl->tName);
safef(tName, sizeof(tName), "%s.%s", organism, psl->tName);
if (qName == NULL)
fprintf(f, "Alignment of %s and %s:%d-%d
\n",
psl->qName, psl->tName, psl->tStart+1, psl->tEnd);
else
fprintf(f, "Alignment of %s and %s:%d-%d
\n",
qName, psl->tName, psl->tStart+1, psl->tEnd);
if (!cartUsualBoolean(cart, "blatNewPage", FALSE)) /* no "frame" in the new single-page view */
fputs("Click on links in the frame to the left to navigate through "
"the alignment.\n", f);
blockCount = pslShowAlignment(psl, qType == gftProt,
qName, qSeq, qStart, qEnd,
tName, tSeq, tStart, tEnd, f);
freeDnaSeq(&tSeq);
return blockCount;
}
static struct ffAli *pslToFfAliAndSequence(struct psl *psl, struct dnaSeq *qSeq,
boolean *retIsRc, struct dnaSeq **retSeq,
int *retTStart)
/* Given psl, dig up target sequence and convert to ffAli.
* Note: if strand is -, this does a pslRc to psl! */
{
int tStart, tEnd, tRcAdjustedStart;
struct dnaSeq *dnaSeq;
tStart = psl->tStart - 100;
if (tStart < 0) tStart = 0;
if (retTStart)
*retTStart = tStart;
tEnd = psl->tEnd + 100;
if (tEnd > psl->tSize) tEnd = psl->tSize;
dnaSeq = hDnaFromSeq(database, seqName, tStart, tEnd, dnaLower);
freez(&dnaSeq->name);
dnaSeq->name = cloneString(psl->tName);
if (retSeq)
*retSeq = dnaSeq;
tRcAdjustedStart = tStart;
if (psl->strand[1] == '-')
pslRc(psl);
if (psl->strand[0] == '-')
{
if (retIsRc)
*retIsRc = TRUE;
reverseComplement(dnaSeq->dna, dnaSeq->size);
pslRc(psl);
tRcAdjustedStart = psl->tSize - tEnd;
}
return pslToFfAli(psl, qSeq, dnaSeq, tRcAdjustedStart);
}
static void ffStartEndQ(char *qDna, struct ffAli *ff, int *retStartQ, int *retEndQ)
/* Return query start and end */
{
if (ff == NULL)
*retStartQ = *retEndQ = 0;
else
{
struct ffAli *right = ffRightmost(ff);
*retStartQ = ff->nStart - qDna;
*retEndQ = right->nEnd - qDna;
}
}
int showPartialDnaAlignment(struct psl *wholePsl,
struct dnaSeq *rnaSeq, FILE *body,
int cdsS, int cdsE, boolean restrictToWindow)
/* Show (part of) alignment for accession. wholePsl is the whole alignment;
* if restrictToWindow then display the part of the alignment in the current
* browser window. */
{
/* Do a consistency check between rnaSeq and psl*/
int rnaSize = rnaSeq->size;
if (rnaSize != wholePsl->qSize)
{
fprintf(body, "Cannot display alignment. Size of rna %s is %d has changed since alignment was performed when it was %d.\n",
wholePsl->qName, rnaSize, wholePsl->qSize);
return 0;
}
/* Possibly just do smaller subset that is within window. */
struct psl *psl = wholePsl;
if (restrictToWindow)
{
psl = pslTrimToTargetRange(wholePsl, winStart, winEnd);
if (psl == NULL)
fprintf(body, "
No alignment of %s within browser window.", wholePsl->qName);
}
struct dnaSeq *dnaSeq;
int wholeTStart;
int partTStart = psl->tStart, partTEnd = psl->tEnd;
DNA *rna = rnaSeq->dna;
boolean isRc = FALSE;
struct ffAli *ffAli;
int blockCount;
/* Don't forget -- this may change psl if on reverse strand! */
ffAli = pslToFfAliAndSequence(psl, rnaSeq, &isRc, &dnaSeq,
&wholeTStart);
int rnaStart = 0;
int rnaEnd = rnaSize;
if (restrictToWindow)
{
/* Find start/end in ffAli, which is clipped to target from PSL and maybe RC'd */
ffStartEndQ(rna, ffAli, &rnaStart, &rnaEnd);
/* Add 100 bases either side if possible */
if (rnaStart >= 100) rnaStart -= 100;
if (rnaEnd + 100 <= rnaSize) rnaEnd += 100;
}
/* Write body heading info. */
char *displayChromName = chromAliasGetDisplayChrom(database, cart, psl->tName);
fprintf(body, "
Alignment of %s and %s:%d-%d
\n",
psl->qName, displayChromName, partTStart+1, partTEnd);
if (!cartUsualBoolean(cart, "blatNewPage", FALSE)) /* no "frame" in the new single-page view */
fprintf(body, "Click on links in the frame to the left to navigate through "
"the alignment.\n");
blockCount = ffShAliPart(body, ffAli, wholePsl->qName,
rna + rnaStart, rnaEnd - rnaStart, rnaStart,
displayChromName, dnaSeq->dna, dnaSeq->size,
wholeTStart, 8, FALSE, isRc,
FALSE, TRUE, TRUE, TRUE, TRUE,
cdsS, cdsE, partTStart, partTEnd);
return blockCount;
}
/* The modern single-page alignment (webStartGbNoBanner chrome, no