e1988a798585c610e2399538a900fd57cfa83d63 galt Tue Apr 22 11:19:22 2025 -0700 Fixes VCF does not work on extended case-color options in Get DNA for vcf, vcfTabix, and vcfPhasedTrio. fixes #16386 diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c index 675531a22db..de021c5b7fe 100644 --- src/hg/hgc/hgc.c +++ src/hg/hgc/hgc.c @@ -5868,30 +5868,41 @@ { AllocVar(fb); fb->name = bed->name; fb->start = bed->chromStart; fb->end = bed->chromEnd; fb->strand = '+'; if (bed->strand[0]) fb->strand = bed->strand[0]; if (clipFbToWindow(fb, winStart,winEnd)) slAddHead(&fbList, fb); } } return fbList; } +static struct featureBits *vcfLoadInterval(struct trackDb *tdb, int start, int end) +{ +struct featureBits *fbList = NULL; +if (sameString(tdb->type, "vcf") || sameString(tdb->type, "vcfPhasedTrio")) + doVcfDetailsExt(tdb, NULL, &fbList, start, end); +else if (sameString(tdb->type, "vcfTabix")) + doVcfTabixDetailsExt(tdb, NULL, &fbList, start, end); +return fbList; +} + + void doGetDna3() /* Fetch DNA in extended color format */ { struct dnaSeq *seq; struct cfm *cfm; int i; boolean isRc = cartUsualBoolean(cart, "hgSeq.revComp", FALSE); boolean defaultUpper = sameString(cartString(cart, "hgSeq.casing"), "upper"); int winSize; int lineWidth = cartInt(cart, "lineWidth"); struct rgbColor *colors; struct trackDb *tdbList = loadTracks(); char *pos = NULL; @@ -5918,30 +5929,31 @@ 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); @@ -5961,31 +5973,31 @@ 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) + 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) @@ -6005,65 +6017,76 @@ 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("big", tdbLeaf->type)) + 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("big", tdb->type)) + 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)) {