13b584581e6d7b1860e0cab97adc3594b1899308 braney Mon Aug 7 12:05:10 2023 -0700 add instaPort to bigBed support diff --git src/hg/hgTracks/bigBedTrack.c src/hg/hgTracks/bigBedTrack.c index a5d7c3b..8f1b6c4 100644 --- src/hg/hgTracks/bigBedTrack.c +++ src/hg/hgTracks/bigBedTrack.c @@ -16,30 +16,31 @@ #include "localmem.h" #include "wigCommon.h" #include "bbiFile.h" #include "obscure.h" #include "bigWig.h" #include "bigBed.h" #include "bigWarn.h" #include "errCatch.h" #include "trackHub.h" #include "net.h" #include "bigPsl.h" #include "bigBedFilter.h" #include "bigBedLabel.h" #include "variation.h" #include "chromAlias.h" +#include "instaPort.h" static unsigned getFieldNum(struct bbiFile *bbi, char *field) // get field number for field name in bigBed. errAbort if field not found. { int fieldNum = bbFieldIndex(bbi, field); if (fieldNum < 0) fieldNum = defaultFieldLocation(field); if (fieldNum < 0) errAbort("error building filter with field %s. Field not found.", field); return fieldNum; } struct bigBedFilter *bigBedMakeNumberFilter(struct cart *cart, struct bbiFile *bbi, struct trackDb *tdb, char *filter, char *defaultLimits, char *field) /* Make a filter on this column if the trackDb or cart wants us to. */ @@ -408,31 +409,30 @@ { char *denseCoverage = trackDbSettingClosestToHome(track->tdb, "denseCoverage"); if (denseCoverage != NULL) { double endVal = atof(denseCoverage); if (endVal <= 0) { AllocVar(track->sumAll); *track->sumAll = bbiTotalSummary(bbi); } } } else freez(&track->summary); } - bbiFileClose(&bbi); track->bbiFile = NULL; } errCatchEnd(errCatch); if (errCatch->gotError) { track->networkErrMsg = cloneString(errCatch->message->string); track->drawItems = bigDrawWarning; track->totalHeight = bigWarnTotalHeight; result = NULL; } errCatchFree(&errCatch); return result; } @@ -449,31 +449,30 @@ if (fieldIdx < restCount) field = cloneString(restFields[fieldIdx]); freeMem(rest); return field; } void bigBedAddLinkedFeaturesFromExt(struct track *track, char *chrom, int start, int end, int scoreMin, int scoreMax, boolean useItemRgb, int fieldCount, struct linkedFeatures **pLfList, int maxItems) /* Read in items in chrom:start-end from bigBed file named in track->bbiFileName, convert * them to linkedFeatures, and add to head of list. */ { struct lm *lm = lmInit(0); struct trackDb *tdb = track->tdb; -struct bigBedInterval *bb, *bbList = bigBedSelectRangeExt(track, chrom, start, end, lm, maxItems); char *mouseOverField = cartOrTdbString(cart, track->tdb, "mouseOverField", NULL); // check if this track can merge large items, this setting must be allowed in the trackDb // stanza for the track, but can be enabled/disabled via trackUi/right click menu so // we also need to check the cart for the current status int mergeCount = 0; boolean doWindowSizeFilter = trackDbSettingOn(track->tdb, MERGESPAN_TDB_SETTING); if (doWindowSizeFilter) { char hasMergedItemsSetting[256]; safef(hasMergedItemsSetting, sizeof(hasMergedItemsSetting), "%s.%s", track->track, MERGESPAN_CART_SETTING); if (cartVarExists(cart, hasMergedItemsSetting)) doWindowSizeFilter = cartInt(cart, hasMergedItemsSetting) == 1; else // save the cart var so javascript can offer the right toggle cartSetInt(cart, hasMergedItemsSetting, 1); @@ -483,30 +482,38 @@ struct errCatch *errCatch = errCatchNew(); if (errCatchStart(errCatch)) { bbi = fetchBbiForTrack(track); } errCatchEnd(errCatch); if (errCatch->gotError) { track->networkErrMsg = cloneString(errCatch->message->string); track->drawItems = bigDrawWarning; track->totalHeight = bigWarnTotalHeight; return; } errCatchFree(&errCatch); +struct bigBedInterval *bb, *bbList; +char *instaFile = cloneString(trackDbSetting(track->tdb, "instaPortUrl")); +struct hash *chainHash = NULL; +if (instaFile) + bbList = instaIntervals(instaFile, bbi, chromName, winStart, winEnd, &chainHash); +else + bbList = bigBedSelectRangeExt(track, chrom, start, end, lm, maxItems); + char *squishField = cartOrTdbString(cart, track->tdb, "squishyPackField", NULL); int squishFieldIdx = bbExtraFieldIndex(bbi, squishField); int seqTypeField = 0; if (sameString(track->tdb->type, "bigPsl")) { seqTypeField = bbExtraFieldIndex(bbi, "seqType"); } int mouseOverIdx = bbExtraFieldIndex(bbi, mouseOverField); track->bbiFile = NULL; struct bigBedFilter *filters = bigBedBuildFilters(cart, bbi, track->tdb) ; if (compositeChildHideEmptySubtracks(cart, track->tdb, NULL, NULL)) @@ -521,30 +528,31 @@ mouseOverPattern = cartOrTdbString(cart, track->tdb, "mouseOver", NULL); if (mouseOverPattern) { AllocArray(fieldNames, bbi->fieldCount); struct slName *field = NULL, *fields = bbFieldNames(bbi); int i = 0; for (field = fields; field != NULL; field = field->next) fieldNames[i++] = field->name; } } // a fake item that is the union of the items that span the current window struct linkedFeatures *spannedLf = NULL; unsigned filtered = 0; +struct bed *bed = NULL, *bedCopy = NULL; for (bb = bbList; bb != NULL; bb = bb->next) { struct linkedFeatures *lf = NULL; char *bedRow[bbi->fieldCount]; if (sameString(track->tdb->type, "bigPsl")) { // fill out bedRow to support mouseOver pattern replacements char startBuf[16], endBuf[16]; bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow)); char *seq, *cds; struct psl *psl = pslFromBigPsl(chromName, bb, seqTypeField, &seq, &cds); int sizeMul = pslIsProtein(psl) ? 3 : 1; boolean isXeno = 0; // just affects grayIx boolean nameGetsPos = FALSE; // we want the name to stay the name @@ -559,34 +567,47 @@ lf->filterColor = itemRgbColumn(bedRow[8]); } else if (sameString(tdb->type, "bigDbSnp")) { // bigDbSnp does not have a score field, but I want to compute the freqSourceIx from // trackDb and settings one time instead of for each item, so I'm overloading scoreMin. int freqSourceIx = scoreMin; lf = lfFromBigDbSnp(tdb, bb, filters, freqSourceIx); } else { char startBuf[16], endBuf[16]; bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow)); if (bigBedFilterInterval(bedRow, filters)) { - struct bed *bed = bedLoadN(bedRow, fieldCount); + if (instaFile) + { + if ((bed = instaBed(bbi, chainHash, bb)) != NULL) + { + bedCopy = cloneBed(bed); lf = bedMungToLinkedFeatures(&bed, tdb, fieldCount, scoreMin, scoreMax, useItemRgb); } + } + else + { + bed = bedLoadN(bedRow, fieldCount); + bedCopy = cloneBed(bed); + lf = bedMungToLinkedFeatures(&bed, tdb, fieldCount, + scoreMin, scoreMax, useItemRgb); + } + } if (lf && squishFieldIdx) lf->squishyPackVal = atof(restField(bb, squishFieldIdx)); if (track->visibility != tvDense && lf && doWindowSizeFilter && bb->start < winStart && bb->end > winEnd) { mergeCount++; struct bed *bed = bedLoadN(bedRow, fieldCount); struct linkedFeatures *tmp = bedMungToLinkedFeatures(&bed, tdb, fieldCount, scoreMin, scoreMax, useItemRgb); if (spannedLf) { if (tmp->start < spannedLf->start) spannedLf->start = tmp->start; if (tmp->end > spannedLf->end) @@ -619,31 +640,31 @@ } continue; // lf will be NULL, but these items aren't "filtered", they're merged } } if (lf == NULL) { filtered++; continue; } if (lf->label == NULL) lf->label = bigBedMakeLabel(track->tdb, track->labelColumns, bb, chromName); if (startsWith("bigGenePred", track->tdb->type) || startsWith("genePred", track->tdb->type)) { - lf->original = genePredFromBigGenePred(chromName, bb); + lf->original = genePredFromBedBigGenePred(chromName, bedCopy, bb); } if (lf->mouseOver == NULL) { if (mouseOverIdx > 0) lf->mouseOver = restField(bb, mouseOverIdx); else if (mouseOverPattern) lf->mouseOver = replaceFieldInPattern(mouseOverPattern, bbi->fieldCount, fieldNames, bedRow); } slAddHead(pLfList, lf); } if (filtered) labelTrackAsFilteredNumber(track, filtered);