a1cfd4eb6e2f1e0eb0e8756fd02ebcb602c77687
kent
Tue Jun 28 13:08:30 2022 -0700
Making base-by-base alignment display work for bigChains and bigPsls.
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index 8efffb4..0c22794 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -257,30 +257,31 @@
#include "bPlusTree.h"
#include "customFactory.h"
#include "iupac.h"
#include "clinvarSubLolly.h"
#include "jsHelper.h"
#include "errCatch.h"
#include "htslib/bgzf.h"
#include "htslib/kstring.h"
#include "pipeline.h"
#include "genark.h"
#include "chromAlias.h"
static char *rootDir = "hgcData";
#define LINESIZE 70 /* size of lines in comp seq feature */
+#define MAX_DISPLAY_QUERY_SEQ_SIZE 5000000 // Big enough for HLA alts
struct cart *cart; /* User's settings. */
char *seqName; /* Name of sequence we're working on. */
int winStart, winEnd; /* Bounds of sequence. */
char *database; /* Name of mySQL database. */
char *organism; /* Colloquial name of organism. */
char *genome; /* common name, e.g. Mouse, Human */
char *scientificName; /* Scientific name of organism. */
/* for earlyBotCheck() function at the beginning of main() */
#define delayFraction 0.5 /* standard penalty is 1.0 for most CGIs */
/* this one is 0.5 */
boolean issueBotWarning = FALSE;
struct hash *trackHash; /* A hash of all tracks - trackDb valued */
@@ -3224,39 +3225,71 @@
}
void pslDumpHtml(struct psl *pslList)
/* print out psl header and data */
{
struct psl* psl;
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 = twoBitReadSeqFrag(otherTbf, psl->qName, 0, 0);
+ *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++;
}
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)
@@ -3313,57 +3346,60 @@
char startBuf[16], endBuf[16];
int lastChromId = -1;
char chromName[bbi->chromBpt->keySize+1];
boolean firstTime = TRUE;
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= pslFromBigPsl(chromName, bb, seqTypeField, &seq, &cdsStr);
+ 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 (differentString(item, "PrintAllSequences") && firstTime && !isEmpty(seq)) // if there is a query sequence
{
firstTime = FALSE;
printf("Links to sequence:
\n");
printf("\n");
if (!isEmpty(cdsStr)) // if we have CDS
{
puts("- \n");
hgcAnchorSomewhere("htcTranslatedBigPsl", item, "translate", seqName);
printf("Translated Amino Acid Sequence from Query Sequence\n");
puts("
\n");
}
+ if (psl->qSize <= MAX_DISPLAY_QUERY_SEQ_SIZE)
+ {
puts("- \n");
hgcAnchorSomewhere("htcBigPslSequence", item, tdb->track, seqName);
printf("Query Sequence \n");
puts("
\n");
printf("
\n");
}
}
}
+ }
char *sort = cartUsualString(cart, "sort", pslSortList[0]);
pslSortListByVar(&pslList, sort);
if (showEvery)
printf("Genomic Alignments
");
else
printf("%s/Genomic Alignments
", item);
if (showEvery || pslIsProtein(pslList))
printAlignmentsSimple(pslList, start, "htcBigPslAli", tdb->table, item);
else
printAlignmentsExtra(pslList, start, "htcBigPslAli", "htcBigPslAliInWindow",
tdb->table, item);
pslFreeList(&pslList);
printItemDetailsHtml(tdb, item);
@@ -3488,30 +3524,49 @@
{
htmlHorizontalLine();
// Add pennantIcon
printPennantIconNote(tdb);
// Wrap description html in div with limited width, so when the page is very wide
// due to long details, the user doesn't have to scroll right to read the description.
puts("");
puts(html);
puts("
");
}
hPrintf("
\n");
}
+struct chain *chainLoadItemInRange(struct trackDb *tdb, char *item)
+/* Load up parts of chain that intersect seqName:winStart-winEnd */
+{
+struct chain *chain = NULL;
+int id = sqlUnsigned(item);
+if (startsWith("big", tdb->type))
+ {
+ char *fileName = trackDbSetting(tdb, "bigDataUrl");
+ char *linkFileName = trackDbSetting(tdb, "linkDataUrl");
+ chain = chainLoadIdRangeHub(database, fileName, linkFileName, seqName, winStart, winEnd, id);
+ }
+else
+ {
+ chain = chainLoadIdRange(database, tdb->table, seqName, winStart, winEnd, id);
+ }
+return chain;
+}
+
+
void qChainRangePlusStrand(struct chain *chain, int *retQs, int *retQe)
/* Return range of bases covered by chain on q side on the plus
* strand. */
{
if (chain == NULL)
errAbort("Can't find range in null query chain.");
if (chain->qStrand == '-')
{
*retQs = chain->qSize - chain->qEnd+1;
*retQe = chain->qSize - chain->qStart;
}
else
{
*retQs = chain->qStart+1;
*retQe = chain->qEnd;
@@ -3585,79 +3640,88 @@
struct chain *subChain = NULL, *toFree = NULL;
int qs,qe;
chainSubsetOnT(chain, winStart, winEnd, &subChain, &toFree);
if (subChain != NULL && otherOrg != NULL)
{
qChainRangePlusStrand(subChain, &qs, &qe);
if (hubUrl)
linkToOtherBrowserHub(otherDb, subChain->qName, qs-1, qe, hubUrl);
else
linkToOtherBrowser(otherDb, subChain->qName, qs-1, qe);
printf("Open %s browser at position corresponding to the part of chain that is in this window.
\n", trackHubSkipHubName(otherOrg));
}
chainFree(&toFree);
}
+struct dnaSeq *otherChromSeq(struct twoBitFile *otherTbf, char *otherDb,
+ char *otherChrom, int otherStart, int otherEnd)
+/* This fetches sequence from tdb->otherTwoBitUrl if available, if not
+ * tries to find it via otherDb */
+{
+if (otherTbf != NULL)
+ {
+ return twoBitReadSeqFrag(otherTbf, otherChrom, otherStart, otherEnd);
+ }
+else
+ {
+ return hChromSeq(otherDb, otherChrom, otherStart, otherEnd);
+ }
+}
+
void genericChainClick(struct sqlConnection *conn, struct trackDb *tdb,
char *item, int start, char *otherDb)
/* Handle click in chain track, at least the basics. */
{
+struct twoBitFile *otherTbf = getOtherTwoBitUrl(tdb);
char *thisOrg = hOrganism(database);
char *otherOrg = NULL;
struct chain *chain = NULL, *subChain = NULL, *toFree = NULL;
int chainWinSize;
double subSetScore = 0.0;
int qs, qe;
boolean nullSubset = FALSE;
boolean otherIsActive = FALSE;
char *hubUrl = NULL; // if otherDb is a genark browser
if (hDbIsActive(otherDb))
otherIsActive = TRUE;
else
hubUrl = genarkUrl(otherDb); // may be NULL
if (! sameWord(otherDb, "seq"))
{
otherOrg = hOrganism(otherDb);
}
if (otherOrg == NULL)
{
/* use first word of chain label (count on org name as first word) */
otherOrg = firstWordInLine(cloneString(tdb->shortLabel));
}
+chain = chainLoadItemInRange(tdb, item);
if (startsWith("big", tdb->type))
{
- char *fileName = bbiNameFromSettingOrTable(tdb, conn, tdb->table);
- char *linkFileName = trackDbSetting(tdb, "linkDataUrl");
- chain = chainLoadIdRangeHub(database, fileName, linkFileName, seqName, winStart, winEnd, atoi(item));
-
if (!otherIsActive) // if this isn't a native database, check to see if it's a hub
{
struct trackHubGenome *genome = trackHubGetGenomeUndecorated(otherDb);
if (genome)
{
otherIsActive = TRUE;
otherDb = genome->name;
}
}
}
-else
- {
- chain = chainLoadIdRange(database, tdb->table, seqName, winStart, winEnd, atoi(item));
- }
chainSubsetOnT(chain, winStart, winEnd, &subChain, &toFree);
if (subChain == NULL)
nullSubset = TRUE;
else if (otherIsActive && subChain != chain)
{
char *linearGap = trackDbSettingOrDefault(tdb, "chainLinearGap", "loose");
struct gapCalc *gapCalc = gapCalcFromFile(linearGap);
struct axtScoreScheme *scoreScheme = axtScoreSchemeDefault();
int qStart = subChain->qStart;
int qEnd = subChain->qEnd ;
struct dnaSeq *tSeq = hDnaFromSeq(database, subChain->tName, subChain->tStart, subChain->tEnd, dnaLower);
struct dnaSeq *qSeq = NULL;
char *matrix = trackDbSetting(tdb, "matrix");
@@ -3670,31 +3734,31 @@
scoreScheme = axtScoreSchemeFromBlastzMatrix(words[1], 400, 30);
}
else
{
if (size != 2)
errAbort("error parsing matrix entry in trackDb, expecting 2 word got %d ",
size);
else
errAbort("error parsing matrix entry in trackDb, size 16 matrix, got %d ",
atoi(words[0]));
}
}
if (subChain->qStrand == '-')
reverseIntRange(&qStart, &qEnd, subChain->qSize);
- qSeq = hChromSeq(otherDb, subChain->qName, qStart, qEnd);
+ qSeq = otherChromSeq(otherTbf, otherDb, subChain->qName, qStart, qEnd);
if (subChain->qStrand == '-')
reverseComplement(qSeq->dna, qSeq->size);
subChain->score = chainCalcScoreSubChain(subChain, scoreScheme, gapCalc,
qSeq, tSeq);
subSetScore = subChain->score;
}
chainFree(&toFree);
printf("%s position: %s:%d-%d"
" size: %d
\n",
trackHubSkipHubName(thisOrg), hgTracksName(), cartSidUrlString(cart), database,
chain->tName, chain->tStart+1, chain->tEnd, chain->tName, chain->tStart+1, chain->tEnd,
chain->tEnd-chain->tStart);
printf("Strand: %c
\n", chain->qStrand);
qChainRangePlusStrand(chain, &qs, &qe);
@@ -3751,31 +3815,33 @@
}
sqlFreeResult(&sr);
printf("
\n");
}
printf("
Fields above refer to entire chain or gap, not just the part inside the window.
\n");
printf("
\n");
chainWinSize = min(winEnd-winStart, chain->tEnd - chain->tStart);
/* Show alignment if the database exists and */
/* if there is a chromInfo table for that database and the sequence */
/* file exists. This means that alignments can be shown on the archive */
/* server (or in other cases) if there is a database with a chromInfo table, */
/* the sequences are available and there is an entry added to dbDb for */
/* the otherDb. */
-if (!startsWith("big", tdb->type) && sqlDatabaseExists(otherDb) && chromSeqFileExists(otherDb, chain->qName))
+if (otherTbf != NULL ||
+ (!startsWith("big", tdb->type) && sqlDatabaseExists(otherDb)
+ && chromSeqFileExists(otherDb, chain->qName)))
{
if (chainWinSize < 1000000)
{
printf("View ");
hgcAnchorSomewhere("htcChainAli", item, tdb->track, chain->tName);
printf("DNA sequence alignment details of parts of chain within browser "
"window.
\n");
}
else
{
printf("Zoom so that browser window covers 1,000,000 bases or less "
"and return here to see alignment details.
\n");
}
}
@@ -4708,34 +4774,30 @@
char *hgsid = cartSessionId(cart);
char *desc = sameString(tdb->table, "altLocations") ? "alternate haplotype" : "fix patch";
printf(""
"Show this %s placed on its chromosome
\n",
hgsid, itemCpy, desc);
}
printTrackHtml(tdb);
freez(&dupe);
hFreeConn(&conn);
}
void genericClickHandler(struct trackDb *tdb, char *item, char *itemForUrl)
/* Put up generic track info */
{
-#ifdef OLD /* Called now by cartWebStart... */
-jsIncludeFile("jquery.js", NULL);
-jsIncludeFile("utils.js",NULL);
-#endif /* OLD */
genericClickHandlerPlus(tdb, item, itemForUrl, NULL);
}
void savePosInTextBox(char *chrom, int start, int end)
/* Save basic position/database info in text box and hidden var.
Positions becomes chrom:start-end*/
{
char position[128];
char *newPos;
snprintf(position, 128, "%s:%d-%d", chrom, start, end);
newPos = addCommasToPos(database, position);
cgiMakeTextVar("getDnaPos", newPos, strlen(newPos) + 2);
cgiContinueHiddenVar("db");
}
@@ -4880,30 +4942,53 @@
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)
@@ -6317,60 +6402,64 @@
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 (sameString(itemIn, "PrintAllSequences"))
qName = 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);
- printf("%5d %5.1f%% %9s %s %9d %9d %20s %5d %5d %5d",
+ 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(psl->tName), 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");
}
}
}
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)
+ && psl->qSize <= MAX_DISPLAY_QUERY_SEQ_SIZE
)
{
char otherString[512];
safef(otherString, sizeof(otherString), "%d&aliTable=%s",
psl->tStart, tableName);
hgcAnchorSomewhere(hgcCommandInWindow, itemIn, 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. */
{
@@ -7727,31 +7816,31 @@
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, 12);
if (sameString(bed->name, acc) && (bb->start == start) && (bb->end == end))
{
bb->next = NULL;
break;
}
}
if (bb == NULL)
errAbort("item %s not found in range %s:%d-%d in bigBed %s (%s)",
acc, chrom, start, end, tdb->table, fileName);
unsigned seqTypeField = bbExtraFieldIndex(bbi, "seqType");
-psl = pslFromBigPsl(seqName, bb, seqTypeField, &seq, &cdsString);
+psl = getPslAndSeq(tdb, seqName, bb, seqTypeField, &seq, &cdsString);
if (cdsString)
genbankParseCds(cdsString, &cdsStart, &cdsEnd);
if (seq == NULL)
{
printf("Sequence for %s not available.\n", psl->qName);
return;
}
struct dnaSeq *rnaSeq = newDnaSeq(seq, strlen(seq), acc);
enum gfType type = gftRna;
if (pslIsProtein(psl))
type = gftProt;
showSomeAlignment(psl, rnaSeq, type, 0, rnaSeq->size, NULL, cdsStart, cdsEnd);
}
@@ -7788,31 +7877,31 @@
struct bbiFile *bbi = bigBedFileOpenAlias(fileName, chromAliasFindAliases);
struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, chrom, start, end, 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, 12);
if (sameString(bed->name, acc))
{
bb->next = NULL;
break;
}
}
unsigned seqTypeField = bbExtraFieldIndex(bbi, "seqType");
-wholePsl = pslFromBigPsl(seqName, bb, seqTypeField, &seq, &cdsString);
+wholePsl = getPslAndSeq(tdb, seqName, bb, seqTypeField, &seq, &cdsString);
if (seq == NULL)
{
printf("Sequence for %s not available.\n", wholePsl->qName);
return;
}
if (cdsString)
genbankParseCds(cdsString, &cdsStart, &cdsEnd);
if (wholePsl->tStart >= winStart && wholePsl->tEnd <= winEnd)
partPsl = wholePsl;
else
partPsl = pslTrimToTargetRange(wholePsl, winStart, winEnd);
struct dnaSeq *rnaSeq = newDnaSeq(seq, strlen(seq), acc);
showSomePartialDnaAlignment(partPsl, wholePsl, rnaSeq,
@@ -8061,109 +8150,118 @@
else
partPsl = pslTrimToTargetRange(wholePsl, winStart, winEnd);
if (startsWith("xeno", aliTable))
errAbort("htcCdnaAliInWindow does not support translated alignments.");
else
showSomePartialDnaAlignment(partPsl, wholePsl, rnaSeq,
NULL, cdsStart, cdsEnd);
}
void htcChainAli(char *item)
/* Draw detailed alignment representation of a chain. */
{
struct chain *chain;
struct psl *fatPsl, *psl = NULL;
-int id = atoi(item);
char *track = cartString(cart, "o");
-char *type = trackTypeInfo(track);
+struct trackDb *tdb = getTdbForTrackName(track);
+char *type = cloneString(tdb->type);
char *typeWords[2];
char *otherDb = NULL, *org = NULL, *otherOrg = NULL;
struct dnaSeq *qSeq = NULL;
char name[128];
-
/* Figure out other database. */
if (chopLine(type, typeWords) < ArraySize(typeWords))
errAbort("type line for %s is short in trackDb", track);
otherDb = typeWords[1];
if (! sameWord(otherDb, "seq"))
{
otherOrg = hOrganism(otherDb);
}
org = hOrganism(database);
/* Load up subset of chain and convert it to part of psl
* that just fits inside of window. */
-chain = chainLoadIdRange(database, track, seqName, winStart, winEnd, id);
+chain = chainLoadItemInRange(tdb, item);
if (chain->blockList == NULL)
{
printf("None of chain is actually in the window");
return;
}
fatPsl = chainToPsl(chain);
chainFree(&chain);
psl = pslTrimToTargetRange(fatPsl, winStart, winEnd);
pslFree(&fatPsl);
+struct twoBitFile *otherTbf = getOtherTwoBitUrl(tdb);
if (sameWord(otherDb, "seq"))
{
qSeq = hExtSeqPart(database, psl->qName, psl->qStart, psl->qEnd);
safef(name, sizeof name, "%s", psl->qName);
}
-else
+else if (otherDb != NULL)
{
qSeq = loadGenomePart(otherDb, psl->qName, psl->qStart, psl->qEnd);
safef(name, sizeof name, "%s.%s", otherOrg, psl->qName);
}
+else if (otherTbf != NULL)
+ {
+ qSeq = twoBitReadSeqFragLower(otherTbf, psl->qName, psl->qStart, psl->qEnd);
+ safef(name, sizeof name, "%s", psl->qName);
+ }
+if (qSeq == NULL)
+ {
+ errAbort("Can't find query sequence in htcChainAli");
+ }
char title[1024];
safef(title, sizeof title, "%s %s vs %s %s ",
(otherOrg == NULL ? "" : otherOrg), psl->qName, org, psl->tName );
htmlFramesetStart(title);
showSomeAlignment(psl, qSeq, gftDnaX, psl->qStart, psl->qEnd, name, 0, 0);
}
void htcChainTransAli(char *item)
/* Draw detailed alignment representation of a chain with translated protein */
{
struct chain *chain;
struct psl *fatPsl, *psl = NULL;
-int id = atoi(item);
char *track = cartString(cart, "o");
char *type = trackTypeInfo(track);
char *typeWords[2];
char *otherDb = NULL, *org = NULL, *otherOrg = NULL;
struct dnaSeq *qSeq = NULL;
char name[128];
int cdsStart = cgiInt("qs");
int cdsEnd = cgiInt("qe");
/* Figure out other database. */
if (chopLine(type, typeWords) < ArraySize(typeWords))
errAbort("type line for %s is short in trackDb", track);
otherDb = typeWords[1];
if (! sameWord(otherDb, "seq"))
{
otherOrg = hOrganism(otherDb);
}
org = hOrganism(database);
/* Load up subset of chain and convert it to part of psl
* that just fits inside of window. */
-chain = chainLoadIdRange(database, track, seqName, winStart, winEnd, id);
+struct trackDb *tdb = getTdbForTrackName(track);
+chain = chainLoadItemInRange(tdb, item);
if (chain->blockList == NULL)
{
printf("None of chain is actually in the window");
return;
}
fatPsl = chainToPsl(chain);
chainFree(&chain);
psl = pslTrimToTargetRange(fatPsl, winStart, winEnd);
pslFree(&fatPsl);
if (sameWord(otherDb, "seq"))
{
qSeq = hExtSeq(database, psl->qName);
@@ -8877,41 +8975,30 @@
struct bbiFile *bbi = bigBedFileOpenAlias(fileName, chromAliasFindAliases);
struct lm *lm = lmInit(0);
struct bigBedInterval *bb, *bbList = bigBedIntervalQuery(bbi, seqName, winStart, winEnd, 0, lm);
struct genePred *gpList = NULL;
for (bb = bbList; bb != NULL; bb = bb->next)
{
struct genePred *gp = (struct genePred *)genePredFromBigGenePred(seqName, bb);
if (sameString(gp->name, geneName))
slAddHead(&gpList, gp);
}
lmCleanup(&lm);
return gpList;
}
-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;
-}
-
static struct genePred *getGenePredForPosition(char *table, char *geneName)
/* Build a genePred list for the given table and gene name. */
{
struct genePred *gpList = NULL;
if (isCustomTrack(table))
{
struct trackDb *tdb = getCustomTrackTdb(table);
gpList = getGenePredForPositionBigGene(tdb, geneName);
}
else if (isHubTrack(table))
{
struct trackDb *tdb = hubConnectAddHubForTrackAndFindTdb( database, table, NULL, trackHash);
gpList = getGenePredForPositionBigGene(tdb, geneName);
}
@@ -8996,31 +9083,31 @@
int lastChromId = -1;
char chromName[bbi->chromBpt->keySize+1];
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);
// 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 sequence
if (sameString(bedRow[3], acc))
{
char *cdsStr, *seq;
- pslFromBigPsl(chromName, bb, seqTypeField, &seq, &cdsStr);
+ getPslAndSeq(tdb, chromName, bb, seqTypeField, &seq, &cdsStr);
if (translate)
{
struct genbankCds cds;
if (!genbankCdsParse(cdsStr, &cds))
errAbort("can't parse CDS for %s: %s", acc, cdsStr);
int protBufSize = ((cds.end-cds.start)/3)+4;
char *prot = needMem(protBufSize);
seq[cds.end] = '\0';
dnaTranslateSome(seq+cds.start, prot, protBufSize);
cartHtmlStart("Protein Translation of query sequence");
displayProteinPrediction(acc, prot);
return;
@@ -14738,30 +14825,31 @@
&& strcmp(otherName,"pig")
&& strcmp(otherName,"cat")
&& strcmp(otherName,"dog")
&& strcmp(otherName,"mouse")
&& strcmp(otherName,"rat")
&& strcmp(otherName,"chicken")
&& strcmp(otherName,"fugu")
&& strcmp(otherName,"tetra")
&& strcmp(otherName,"zebrafish")))
{
safef( chromStr, sizeof chromStr, "%sChrom" , otherName );
longXenoPsl1zoo2(tdb, item, otherName, chromStr );
}
}
+#ifdef OLD
struct chain *getChainFromRange(char *chainTable, char *chrom, int chromStart, int chromEnd)
/* get a list of chains for a range */
{
char chainTable_chrom[256];
struct dyString *dy = dyStringNew(128);
struct chain *chainList = NULL;
struct sqlConnection *conn = hAllocConn(database);
safef(chainTable_chrom, 256, "%s_%s",chrom, chainTable);
if (hTableExists(database, chainTable_chrom) )
{
/* lookup chain if not stored */
char **row;
struct sqlResult *sr = NULL;
@@ -14789,30 +14877,31 @@
qEnd = qSize - qStart;
qStart = tmp;
}
chain = NULL;
if (chainId != 0)
{
chain = chainLoadIdRange(database, chainTable, chrom, chromStart, chromEnd, chainId);
if (chain != NULL)
slAddHead(&chainList, chain);
}
}
sqlFreeResult(&sr);
}
return chainList;
}
+#endif /* OLD */
void htcPseudoGene(char *htcCommand, char *item)
/* Interface for selecting & displaying alignments from axtInfo
* for an item from a genePred table. */
{
struct genePred *gp = NULL;
struct axtInfo *aiList = NULL;
struct axt *axtList = NULL;
struct sqlResult *sr;
char **row;
char trackTemp[256];
char *track = cartString(cart, "o");
char *chrom = cartString(cart, "c");
char *name = cartOptionalString(cart, "i");
char *db2 = cartString(cart, "db2");