fbdc691703e4bc2d98fcdb2014fe6fa19771c104 braney Fri Feb 10 17:05:10 2017 -0800 make building a custom track with blat results an option on the hgBlat page. Add some features to bigPsl click support to get the same kind of UI that hgBlat provides. diff --git src/hg/hgBlat/hgBlat.c src/hg/hgBlat/hgBlat.c index fbb2ec7..829dcba 100644 --- src/hg/hgBlat/hgBlat.c +++ src/hg/hgBlat/hgBlat.c @@ -32,31 +32,30 @@ boolean orgChange = FALSE; boolean dbChange = FALSE; struct serverTable /* Information on a server. */ { char *db; /* Database name. */ char *genome; /* Genome name. */ boolean isTrans; /* Is tranlated to protein? */ char *host; /* Name of machine hosting server. */ char *port; /* Port that hosts server. */ char *nibDir; /* Directory of sequence files. */ }; char *typeList[] = {"BLAT's guess", "DNA", "protein", "translated RNA", "translated DNA"}; -char *sortList[] = {"query,score", "query,start", "chrom,score", "chrom,start", "score"}; char *outputList[] = {"hyperlink", "psl", "psl no header"}; #ifdef LOWELAB int minMatchShown = 14; #else int minMatchShown = 20; #endif static struct serverTable *trackHubServerTable(char *db, boolean isTrans) /* Find out if database is a track hub with a blat server */ { char *host, *port; if (!trackHubGetBlatParams(db, isTrans, &host, &port)) return NULL; @@ -203,214 +202,148 @@ ++same; } return same; } boolean allDigits(char *s) /* Return TRUE if s is all digits */ { char c; while ((c = *s++) != 0) if (!isdigit(c)) return FALSE; return TRUE; } -int cmpChrom(char *a, char *b) -/* Compare two chromosomes. */ -{ -return cmpStringsWithEmbeddedNumbers(a, b); -} - -int pslCmpTargetScore(const void *va, const void *vb) -/* Compare to sort based on target then score. */ -{ -const struct psl *a = *((struct psl **)va); -const struct psl *b = *((struct psl **)vb); -int diff = cmpChrom(a->tName, b->tName); -if (diff == 0) - diff = pslScore(b) - pslScore(a); -return diff; -} - -int pslCmpTargetStart(const void *va, const void *vb) -/* Compare to sort based on target start. */ -{ -const struct psl *a = *((struct psl **)va); -const struct psl *b = *((struct psl **)vb); -int diff = cmpChrom(a->tName, b->tName); -if (diff == 0) - diff = a->tStart - b->tStart; -return diff; -} - void printLuckyRedirect(char *browserUrl, struct psl *psl, char *database, char *pslName, char *faName, char *uiState, char *unhideTrack) /* Print out a very short page that redirects us. */ { char url[1024]; safef(url, sizeof(url), "%s?position=%s:%d-%d&db=%s&ss=%s+%s&%s%s", browserUrl, psl->tName, psl->tStart + 1, psl->tEnd, database, pslName, faName, uiState, unhideTrack); /* htmlStart("Redirecting"); */ /* Odd it appears that we've already printed the Content-Typ:text/html line but I can't figure out where... */ htmStart(stdout, "Redirecting"); char javascript[1024]; safef(javascript, sizeof javascript, "location.replace('%s');", url); jsInline(javascript); printf("", url); htmlEnd(); } -static char *replaceSuffix(char *input, char *newSuffix) -/* Given a filename with a suffix, replace existing suffix with a new suffix. */ -{ -char buffer[4096]; -safecpy(buffer, sizeof buffer, input); -char *dot = strrchr(buffer, '.'); -safecpy(dot+1, sizeof buffer - 1 - (dot - buffer), newSuffix); -return cloneString(buffer); -} -static void makeBigPsl(char *pslName, char *faName, char *db, char *outputBigBed) -/* Make a bigPsl with the blat results. */ -{ -char *bigPslFile = replaceSuffix(outputBigBed, "bigPsl"); - -char cmdBuffer[4096]; -safef(cmdBuffer, sizeof(cmdBuffer), "loader/pslToBigPsl %s -fa=%s stdout | sort -k1,1 -k2,2n > %s", pslName, faName, bigPslFile); -system(cmdBuffer); -char buf[4096]; -char *twoBitDir; -if (trackHubDatabase(db)) - { - struct trackHubGenome *genome = trackHubGetGenome(db); - twoBitDir = genome->twoBitPath; - } -else - { - safef(buf, sizeof(buf), "/gbdb/%s", db); - twoBitDir = hReplaceGbdbSeqDir(buf, db); - safef(buf, sizeof(buf), "%s%s.2bit", twoBitDir, db); - twoBitDir = buf; - } - -safef(cmdBuffer, sizeof(cmdBuffer), "loader/bedToBigBed -verbose=0 -udcDir=%s -extraIndex=name -sizesIs2Bit -tab -as=loader/bigPsl.as -type=bed9+16 %s %s %s", - udcDefaultDir(), bigPslFile, twoBitDir, outputBigBed); -system(cmdBuffer); -unlink(bigPslFile); -} +/* forward declaration to reduce churn */ +static void getCustomName(char *database, struct cart *cart, struct psl *psl, char **pName, char **pDescription); void showAliPlaces(char *pslName, char *faName, char *customText, char *database, enum gfType qType, enum gfType tType, char *organism, boolean feelingLucky) /* Show all the places that align. */ { +boolean useBigPsl = cfgOptionBooleanDefault("useBlatBigPsl", FALSE); struct lineFile *lf = pslFileOpen(pslName); struct psl *pslList = NULL, *psl; char *browserUrl = hgTracksName(); char *hgcUrl = hgcName(); char uiState[64]; char *vis; char unhideTrack[64]; -char *sort = cartUsualString(cart, "sort", sortList[0]); +char *sort = cartUsualString(cart, "sort", pslSortList[0]); char *output = cartUsualString(cart, "output", outputList[0]); boolean pslOut = startsWith("psl", output); boolean isStraightNuc = (qType == gftRna || qType == gftDna); int minThreshold = (isStraightNuc ? minMatchShown : 0); sprintf(uiState, "%s=%s", cartSessionVarName(), cartSessionId(cart)); /* If user has hidden BLAT track, add a setting that will unhide the track if user clicks on a browser link. */ vis = cartOptionalString(cart, "hgUserPsl"); if (vis != NULL && sameString(vis, "hide")) snprintf(unhideTrack, sizeof(unhideTrack), "&hgUserPsl=dense"); else unhideTrack[0] = 0; while ((psl = pslNext(lf)) != NULL) { if (psl->match >= minThreshold) slAddHead(&pslList, psl); } lineFileClose(&lf); if (pslList == NULL) { puts("
Sorry, no matches found |
"); if (!sameString(output, "psl no header")) pslxWriteHead(stdout, qType, tType); for (psl = pslList; psl != NULL; psl = psl->next) pslTabOut(psl, stdout); printf(""); } else { printf("
Go back to %s on the Genome Browser.
\n", browserUrl, posStr); + if (useBigPsl) + { + char *trackName = NULL; + char *trackDescription = NULL; + getCustomName(database, cart, pslList, &trackName, &trackDescription); + psl = pslList; + printf("", + hgcUrl, psl->tStart, psl->tEnd,cgiEncode(trackName), cgiEncode(trackDescription), pslName, cgiEncode(faName), psl->qName, psl->tName, + psl->tStart, psl->tEnd, database, uiState); + + //printf( + //"", trackDescription); + //printf("Description: %s\n", trackDescription); + //printf("\n"); + //printf(""); + } + printf(""); printf(" ACTIONS QUERY SCORE START END QSIZE IDENTITY CHRO STRAND START END SPAN\n"); printf("---------------------------------------------------------------------------------------------------\n"); for (psl = pslList; psl != NULL; psl = psl->next) { if (customText) printf("", browserUrl, psl->tName, psl->tStart + 1, psl->tEnd, database, customText, uiState, unhideTrack); else printf("", browserUrl, psl->tName, psl->tStart + 1, psl->tEnd, database, pslName, faName, uiState, unhideTrack); printf("browser "); printf("", @@ -605,68 +538,33 @@ else if (count == 2) { safef(shortName, sizeof shortName, "blat %s+%d", names->name, count - 1); safef(description, sizeof description, "blat on %d queries (%s, %s)", count, names->name, names->next->name); } else { safef(shortName, sizeof shortName, "blat %s+%d", names->name, count - 1); safef(description, sizeof description, "blat on %d queries (%s, %s, ...)", count, names->name, names->next->name); } *pName = makeNameUnique(shortName, database, cart); *pDescription = cloneString(description); } -static char *outBigPsl(char *db, struct psl *pslList, char *pslFilename, char *faFilename, boolean isProt) -// Make a bigPsl from a list of psls and return its name. -{ -struct tempName bigBedTn; -trashDirDateFile(&bigBedTn, "hgBlat", "bp", ".bb"); -char *bigBedFile = bigBedTn.forCgi; -makeBigPsl(pslFilename, faFilename, db, bigBedFile); -char *customTextFile = replaceSuffix(bigBedFile, "txt"); -FILE *fp = fopen(customTextFile, "w"); -char* host = getenv("HTTP_HOST"); -char* reqUrl = getenv("REQUEST_URI"); -// remove everything after / in URL -char *e = strrchr(reqUrl, '/'); -if (e) *e = 0; - -char *trackName = NULL; -char *trackDescription = NULL; - -getCustomName(db, cart, pslList, &trackName, &trackDescription); -char *customTextTemplate = "track type=bigPsl indelDoubleInsert=on indelQueryInsert=on pslFile=%s visibility=pack showAll=on htmlUrl=http://%s/goldenPath/help/hgUserPsl.html %s bigDataUrl=http://%s%s/%s name=\"%s\" description=\"%s\"\n"; -char *extraForMismatch = "showDiffBasesAllScales=. baseColorUseSequence=lfExtra baseColorDefault=diffBases"; - -if (isProt) - extraForMismatch = ""; -fprintf(fp, customTextTemplate, bigBedTn.forCgi, host, extraForMismatch, host, reqUrl, bigBedTn.forCgi, trackName, trackDescription); -fclose(fp); - -char buffer[4096]; -safef(buffer, sizeof buffer, "http://%s%s/%s", host, reqUrl, customTextFile); - -return cloneString(buffer); -} - void blatSeq(char *userSeq, char *organism, char *database) /* Blat sequence user pasted in. */ { -boolean doHyper = sameString(cartUsualString(cart, "output", outputList[0]), "hyperlink");; -boolean useBigPsl = cfgOptionBooleanDefault("useBlatBigPsl", FALSE) && doHyper; FILE *f; struct dnaSeq *seqList = NULL, *seq; struct tempName pslTn, faTn; int maxSingleSize, maxTotalSize, maxSeqCount; int minSingleSize = minMatchShown; char *genome, *db; char *type = cgiString("type"); char *seqLetters = cloneString(userSeq); struct serverTable *serve; int conn; int oneSize, totalSize = 0, seqCount = 0; boolean isTx = FALSE; boolean isTxTx = FALSE; boolean txTxBoth = FALSE; struct gfOutput *gvo; @@ -842,48 +740,32 @@ { gfAlignTrans(&conn, serve->nibDir, seq, 5, tFileCache, gvo); } } else { gfAlignStrand(&conn, serve->nibDir, seq, FALSE, minMatchShown, tFileCache, gvo); reverseComplement(seq->dna, seq->size); conn = gfConnect(serve->host, serve->port); gfAlignStrand(&conn, serve->nibDir, seq, TRUE, minMatchShown, tFileCache, gvo); } gfOutputQuery(gvo, f); } carefulClose(&f); -if (useBigPsl) - { - struct psl *pslList = pslLoadAll(pslTn.forCgi); - - if (pslList != NULL) - { - char *customTrack = outBigPsl(database, pslList, pslTn.forCgi, faTn.forCgi, qIsProt); - showAliPlaces(pslTn.forCgi, faTn.forCgi, customTrack, serve->db, qType, tType, - organism, feelingLucky); - } - else - puts("
Sorry, no matches found |