7e5840e03baf4a7b7c198016c393d0b86f7b72b6 braney Tue Nov 16 15:25:19 2021 -0800 allow hgc pages on chains to provide a link to the "other" browser if the other assembly is an unattached genark assembly hub diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c index 499b83e..851766f 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -252,30 +252,31 @@ #include "bigPsl.h" #include "bedTabix.h" #include "longRange.h" #include "hmmstats.h" #include "aveStats.h" #include "trix.h" #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" static char *rootDir = "hgcData"; #define LINESIZE 70 /* size of lines in comp seq feature */ 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 */ @@ -3530,119 +3531,139 @@ if (!hFindSplitTable(db, seqName, track, table, sizeof table, &hasBin)) errAbort("No %s track in database %s for %s", track, db, seqName); sqlSafef(query, sizeof(query), "select * from %s where id = %d", table, id); sr = sqlGetResult(conn, query); row = sqlNextRow(sr); if (row == NULL) errAbort("Can't find %d in %s", id, table); chain = chainHeadLoad(row + hasBin); sqlFreeResult(&sr); chainDbAddBlocks(chain, track, conn); return chain; } +void linkToOtherBrowserHub(char *otherDb, char *chrom, int start, int end, char *hubUrl) +/* Make anchor tag to open another browser window. */ +{ +printf("<A TARGET=\"_blank\" HREF=\"%s?genome=%s&position=%s%%3A%d-%d&hubUrl=%s\">", + hgTracksName(), otherDb, chrom, start+1, end, hubUrl); +} + void linkToOtherBrowserExtra(char *otherDb, char *chrom, int start, int end, char *extra) /* Make anchor tag to open another browser window. */ { printf("<A TARGET=\"_blank\" HREF=\"%s?db=%s&%s&position=%s%%3A%d-%d\">", hgTracksName(), otherDb, extra, chrom, start+1, end); } void linkToOtherBrowserSearch(char *otherDb, char *tag) /* Make anchor tag to open another browser window. */ { printf("<A TARGET=\"_blank\" HREF=\"%s?db=%s&ct=&position=%s\">", hgTracksName(), otherDb, tag); } void linkToOtherBrowser(char *otherDb, char *chrom, int start, int end) /* Make anchor tag to open another browser window. */ { printf("<A TARGET=\"_blank\" HREF=\"%s?db=%s&ct=&position=%s%%3A%d-%d\">", hgTracksName(), otherDb, chrom, start+1, end); } void linkToOtherBrowserTitle(char *otherDb, char *chrom, int start, int end, char *title) /* Make anchor tag to open another browser window. */ { printf("<A TARGET=\"_blank\" TITLE=\"%s\" HREF=\"%s?db=%s&ct=&position=%s%%3A%d-%d\">", title, hgTracksName(), otherDb, chrom, start+1, end); } -void chainToOtherBrowser(struct chain *chain, char *otherDb, char *otherOrg) +void chainToOtherBrowser(struct chain *chain, char *otherDb, char *otherOrg, char *hubUrl) /* Put up link that lets us use chain to browser on * corresponding window of other species. */ { struct chain *subChain = NULL, *toFree = NULL; int qs,qe; chainSubsetOnT(chain, winStart, winEnd, &subChain, &toFree); if (subChain != NULL && otherOrg != NULL) { qChainRangePlusStrand(subChain, &qs, &qe); - linkToOtherBrowserExtra(otherDb, subChain->qName, qs-1, qe, cartSidUrlString(cart)); + if (hubUrl) + linkToOtherBrowserHub(otherDb, subChain->qName, qs-1, qe, hubUrl); + else + linkToOtherBrowser(otherDb, subChain->qName, qs-1, qe); printf("Open %s browser</A> at position corresponding to the part of chain that is in this window.<BR>\n", trackHubSkipHubName(otherOrg)); } chainFree(&toFree); } void genericChainClick(struct sqlConnection *conn, struct trackDb *tdb, char *item, int start, char *otherDb) /* Handle click in chain track, at least the basics. */ { 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)); } if (startsWith("big", tdb->type)) { char *fileName = bbiNameFromSettingOrTable(tdb, conn, tdb->table); char *linkFileName = trackDbSetting(tdb, "linkDataUrl"); chain = chainLoadIdRangeHub(fileName, linkFileName, seqName, winStart, winEnd, atoi(item)); - if (!hDbIsActive(otherDb)) // if this isn't a native database, check to see if it's a hub + 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 (hDbIsActive(otherDb) && subChain != chain) +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"); if (matrix != NULL) { char *words[64]; int size = chopByWhite(matrix, words, 64) ; if (size == 2 && atoi(words[0]) == 16) { @@ -3675,44 +3696,47 @@ 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("<B>Strand:</B> %c<BR>\n", chain->qStrand); qChainRangePlusStrand(chain, &qs, &qe); if (sameWord(otherDb, "seq")) { printf("<B>%s position:</B> %s:%d-%d size: %d<BR>\n", otherOrg, chain->qName, qs, qe, chain->qEnd - chain->qStart); } else { /* prints link to other db browser only if db exists and is active */ /* else just print position with no link for the other db */ printf("<B>%s position: </B>", otherOrg); - if (hDbIsActive(otherDb)) + if (otherIsActive) printf(" <A target=\"_blank\" href=\"%s?db=%s&position=%s%%3A%d-%d\">", hgTracksName(), otherDb, chain->qName, qs, qe); + else if (hubUrl != NULL) + printf(" <A target=\"_blank\" href=\"%s?genome=%s&hubUrl=%s&position=%s%%3A%d-%d\">", + hgTracksName(), otherDb, hubUrl, chain->qName, qs, qe); printf("%s:%d-%d", chain->qName, qs, qe); - if (hDbIsActive(otherDb)) + if (otherIsActive || hubUrl) printf("</A>"); printf(" size: %d<BR>\n", chain->qEnd - chain->qStart); } printf("<B>Chain ID:</B> %s<BR>\n", item); printf("<B>Score:</B> %1.0f\n", chain->score); if (nullSubset) printf("<B>Score within browser window:</B> N/A (no aligned bases)<BR>\n"); -else if (hDbIsActive(otherDb) && subChain != chain) +else if (otherIsActive && subChain != chain) printf("<B> Approximate Score within browser window:</B> %1.0f<BR>\n", subSetScore); else printf("<BR>\n"); boolean normScoreAvailable = chainDbNormScoreAvailable(tdb); if (normScoreAvailable) { char tableName[HDB_MAX_TABLE_STRING]; if (!hFindSplitTable(database, chain->tName, tdb->table, tableName, sizeof tableName, NULL)) errAbort("genericChainClick track %s not found", tdb->table); char query[256]; struct sqlResult *sr; char **row; @@ -3742,33 +3766,34 @@ if (!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</A> details of parts of chain within browser " "window.<BR>\n"); } else { printf("Zoom so that browser window covers 1,000,000 bases or less " "and return here to see alignment details.<BR>\n"); } } -if (!sameWord(otherDb, "seq") && (hDbIsActive(otherDb))) + +if (!sameWord(otherDb, "seq") && (otherIsActive || hubUrl)) { - chainToOtherBrowser(chain, otherDb, otherOrg); + chainToOtherBrowser(chain, otherDb, otherOrg, hubUrl); } /* if (!sameWord(otherDb, "seq") && (hDbIsActive(otherDb))) { chainToOtherBrowser(chain, otherDb, otherOrg); } */ chainFree(&chain); } char *trackTypeInfo(char *track) /* Return type info on track. You can freeMem result when done. */ { struct slName *trackDbs = hTrackDbList(), *oneTrackDb; struct sqlConnection *conn = hAllocConn(database); @@ -3900,31 +3925,31 @@ else { printf("Odd, net not in window<BR>\n"); } } else { printf("To see alignment details zoom so that the browser window covers 1,000,000 bases or less.<BR>\n"); } } chain = chainDbLoad(conn, database, chainTrack, seqName, net->chainId); if (chain != NULL) { /* print link to browser for otherDb only if otherDb is active */ if (hDbIsActive(otherDb)) - chainToOtherBrowser(chain, otherDb, otherOrgBrowser); + chainToOtherBrowser(chain, otherDb, otherOrgBrowser, NULL); chainFree(&chain); } htmlHorizontalLine(); } printf("<B>Type:</B> %s<BR>\n", net->type); printf("<B>Level:</B> %d<BR>\n", (net->level+1)/2); printf("<B>%s position:</B> %s:%d-%d<BR>\n", org, net->tName, net->tStart+1, net->tEnd); printf("<B>%s position:</B> %s:%d-%d<BR>\n", otherOrg, net->qName, net->qStart+1, net->qEnd); printf("<B>Strand:</B> %c<BR>\n", net->strand[0]); printLabeledNumber(NULL, "Score", net->score); if (net->chainId) { printf("<B>Chain ID:</B> %u<BR>\n", net->chainId);