1cbb143dea2cf4ece990707556b4c2caac7f0311 braney Thu Mar 21 13:50:58 2024 -0700 fixing bugs in quickLift diff --git src/hg/hgTracks/bedTrack.c src/hg/hgTracks/bedTrack.c index e06b1d4..4debf33 100644 --- src/hg/hgTracks/bedTrack.c +++ src/hg/hgTracks/bedTrack.c @@ -5,30 +5,31 @@ #include "common.h" #include "jksql.h" #include "bed.h" #include "hdb.h" #include "bedCart.h" #include "bbiFile.h" #include "bigBed.h" #include "hgTracks.h" #include "cds.h" #include "bedTabix.h" #include "obscure.h" #include "bigBedFilter.h" #include "bigBedLabel.h" #include "snake.h" +#include "quickLift.h" #define SEQ_DELIM '~' struct bed *bedLoadPairedTagAlign(char **row) /* Load first six fields of bed. * Add ~seq1~seq2 to end of name * Then remove the sequence to extra field when we convert to linkedFeature. * Assumes seq1 and seq2 are in row[6] and row[7], as they would be with a * pairedTagAlign type (hg/lib/encode/pairedTagAlign.as). It would be good to be * able to check these columns exist but we dont have the sqlResult here. */ { char buf[1024]; struct bed *ret = bedLoad6(row); safef(buf, sizeof(buf), "%s%c%s%c%s", ret->name, SEQ_DELIM, row[6], SEQ_DELIM, row[7]); freez(&(ret->name)); @@ -72,52 +73,65 @@ } } /* Get list of items */ if (startsWith("bedTabix", tg->tdb->type ) || startsWith("longTabix", tg->tdb->type )) { struct hash *settings = tg->tdb->settingsHash; char *bigDataUrl = hashFindVal(settings, "bigDataUrl"); struct bedTabixFile *btf = bedTabixFileMayOpen(bigDataUrl, NULL, 0, 0); list = bedTabixReadBeds(btf, chromName, winStart, winEnd, loader); bedTabixFileClose(&btf); } else if (tg->isBigBed) { // avoid opening an unneeded db connection for bigBed; required not to use mysql for parallel fetch tracks struct lm *lm = lmInit(0); - struct bigBedInterval *bb, *bbList = bigBedSelectRange(tg, chromName, winStart, winEnd, lm); struct bbiFile *bbi = fetchBbiForTrack(tg); + char *quickLiftFile = cloneString(trackDbSetting(tg->tdb, "quickLiftUrl")); + struct hash *chainHash = NULL; + struct bigBedInterval *bb, *bbList = NULL; + if (quickLiftFile) + bbList = quickLiftIntervals(quickLiftFile, bbi, chromName, winStart, winEnd, &chainHash); + else + bbList = bigBedSelectRange(tg, chromName, winStart, winEnd, lm); + char *bedRow[bbi->fieldCount]; char startBuf[16], endBuf[16]; struct bigBedFilter *filters = bigBedBuildFilters(cart, bbi, tg->tdb); if (compositeChildHideEmptySubtracks(cart, tg->tdb, NULL, NULL)) labelTrackAsHideEmpty(tg); if (tg->itemName == bedName && !trackDbSettingClosestToHomeOn(tg->tdb, "linkIdInName")) tg->itemName = bigBedItemName; bigBedLabelCalculateFields(cart, tg->tdb, bbi, &tg->labelColumns); unsigned filtered = 0; for (bb = bbList; bb != NULL; bb = bb->next) { bigBedIntervalToRow(bb, chromName, startBuf, endBuf, bedRow, ArraySize(bedRow)); if (!bigBedFilterInterval(bbi, bedRow, filters)) { filtered++; continue; } + if (quickLiftFile) + { + if ((bed = quickLiftBed(bbi, chainHash, bb)) == NULL) + continue; + } + else bed = loader(bedRow); // FIXME BRANEY: either disable for all tracks with NUM_FIELDS > label field or better, // fix how label is stored so it doesn't trash custom bed field // BRANEY says: the loader should be returning bed structures which include the label field. if (differentString(tg->tdb->type, "bigInteract")) bed->label = bigBedMakeLabel(tg->tdb, tg->labelColumns, bb, chromName); slAddHead(&list, bed); } if (filtered) labelTrackAsFilteredNumber(tg, filtered); lmCleanup(&lm); }