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/hgc/hgc.c src/hg/hgc/hgc.c index be8b9f3..9c58a17 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -244,30 +244,31 @@ #include "parClick.h" #include "mdb.h" #include "yaleGencodeAssoc.h" #include "itemDetailsHtml.h" #include "trackVersion.h" #include "numtsClick.h" #include "geneReviewsClick.h" #include "bigBed.h" #include "bigPsl.h" #include "bedTabix.h" #include "longRange.h" #include "hmmstats.h" #include "aveStats.h" #include "trix.h" #include "bPlusTree.h" +#include "customFactory.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. */ struct hash *trackHash; /* A hash of all tracks - trackDb valued */ @@ -2969,41 +2970,54 @@ 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 = bigBedFileOpen(fileName); 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; +struct bigBedInterval *bb, *bbList = NULL; // If showAll is on, show all alignments with this qName, not just the // selected one. -if (showAll) +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); - struct lm *lm = lmInit(0); 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)) { int bedSize = 25; int restBedFields = bedSize - 3; @@ -3017,39 +3031,45 @@ } } char *bedRow[32]; char startBuf[16], endBuf[16]; 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); - if (sameString(bedRow[3], item)) + if (showEvery || sameString(bedRow[3], item)) { struct psl *psl= pslFromBigPsl(chromName, bb, seqTypeField, NULL, NULL); slAddHead(&pslList, psl); } } +char *sort = cartUsualString(cart, "sort", pslSortList[0]); +pslSortListByVar(&pslList, sort); + +if (showEvery) + printf("<H3>Genomic Alignments</H3>"); +else printf("<H3>%s/Genomic Alignments</H3>", item); -if (pslIsProtein(pslList)) +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); } void genericPslClick(struct sqlConnection *conn, struct trackDb *tdb, char *item, int start, char *subType) /* Handle click in generic psl track. */ { struct psl* pslList = getAlignments(conn, tdb->table, item); /* check if there is an alignment available for this sequence. This checks @@ -5868,51 +5888,55 @@ */ { 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 = sameString(itemIn, "PrintAllSequences"); -if (aliCount > 1) +if (!showEvery && (aliCount > 1)) printf("The alignment you clicked on is first in the table below.<BR>\n"); printf("<PRE><TT>"); 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 (sameString(itemIn, "PrintAllSequences")) + qName = psl->qName; safef(otherString, sizeof(otherString), "%d&aliTable=%s", psl->tStart, tableName); printf("<A HREF=\"%s&db=%s&position=%s%%3A%d-%d\">browser</A> | ", hgTracksPathAndSettings(), database, psl->tName, psl->tStart+1, psl->tEnd); - hgcAnchorWindow(hgcCommand, itemIn, psl->tStart, psl->tEnd, otherString, psl->tName); + hgcAnchorWindow(hgcCommand, qName, psl->tStart, psl->tEnd, otherString, psl->tName); printf("%5d %5.1f%% %9s %s %9d %9d %20s %5d %5d %5d</A>", 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); printf("\n"); } } } printf("</TT></PRE>"); } 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. */ @@ -25111,30 +25135,111 @@ while (*c != 0) { if ((*c=='&') || (*c=='<')) doNotBreak = TRUE; if (*c==';' || (*c =='>')) doNotBreak = FALSE; printf("%c", *c); if (i % distance == 0 && ! doNotBreak) printf("<wbr>"); c++; i++; } } +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); +} + +static void buildBigPsl(char *fileNames) +/* Build a custom track with a bigPsl file out of blat results. + * Bring up the bigPsl detail page with all the alignments. */ +{ +char *trackName = cartString(cart, "trackName"); +char *trackDescription = cartString(cart, "trackDescription"); +char *pslName, *faName, *qName; +parseSs(fileNames, &pslName, &faName, &qName); + +struct tempName bigBedTn; +trashDirDateFile(&bigBedTn, "hgBlat", "bp", ".bb"); +char *bigBedFile = bigBedTn.forCgi; +makeBigPsl(pslName, faName, database, bigBedFile); + +char* host = getenv("HTTP_HOST"); +char* reqUrl = cloneString(getenv("REQUEST_URI")); +// delete arguements to the url +char *e = strchr(reqUrl+1, '?'); +if (e) *e = 0; +// remove the cgi name +e = strchr(reqUrl+1, '/'); +if (e) *e = 0; + +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"; + +boolean isProt = FALSE; +if (isProt) + extraForMismatch = ""; +char buffer[4096]; +safef(buffer, sizeof buffer, customTextTemplate, bigBedTn.forCgi, host, extraForMismatch, host, reqUrl, bigBedTn.forCgi, trackName, trackDescription); + +struct customTrack *ctList = getCtList(); +struct customTrack *newCts = customFactoryParse(database, buffer, FALSE, NULL); +theCtList = customTrackAddToList(ctList, newCts, NULL, FALSE); + +customTracksSaveCart(database, cart, theCtList); + +cartSetString(cart, "i", "PrintAllSequences"); +hgCustom(newCts->tdb->track, NULL); +} + void doMiddle() /* Generate body of HTML. */ { char *track = cartString(cart, "g"); char *item = cloneString(cartOptionalString(cart, "i")); char *parentWigMaf = cartOptionalString(cart, "parentWigMaf"); struct trackDb *tdb = NULL; if (hIsGisaidServer()) { validateGisaidUser(cart); } /* database and organism are global variables used in many places */ @@ -25266,30 +25371,34 @@ { doGetDna1(); } else if (sameWord(table, "htcGetDna2")) { doGetDna2(); } else if (sameWord(table, "htcGetDna3")) { doGetDna3(); } else if (sameWord(table, "htcGetDnaExtended1")) { doGetDnaExtended1(); } +else if (sameWord(table, "buildBigPsl")) + { + buildBigPsl(item); + } else if (sameWord(table, "htcListItemsAssayed")) { doPeakClusterListItemsAssayed(); } /* Lowe Lab Stuff */ #ifdef LOWELAB else if (loweLabClick(table, item, tdb)) { /* do nothing, everything handled in loweLabClick */ } #endif else if (sameWord(table, G_DELETE_WIKI_ITEM)) { doDeleteWikiItem(item, seqName, winStart, winEnd);