7f65d3da8f2138d847f15a8398f8dcee1a079027 braney Fri Aug 7 12:07:59 2026 -0700 quickLift: clip an oversized item to the chains we loaded instead of dropping it, refs #38042 quickLift loads chains for the window plus padding, capped at 1 Mb. An item that reaches further than that has ends where no chain reaches, remapRangeList can place neither of them, and the whole item is dropped even though the part on screen maps fine. ClinVar copy number variants run to 159 Mb, so 44 of the 46 in one window disappeared. Pull the ends in to what the chains cover before mapping. The browser never draws the ends of an item that spans the window, so their exact position does not matter, and the existing spanned-item merge still reports it. A clipped end is snapped to a base inside an aligned block, since remapRangeList will only place a coordinate that lands on real alignment. The clip is in the quickLift code, not the shared liftOver remap path. Only hgTracks asks for it, so the details page keeps the item's true extent. Gated by quickLiftClipToChains, on by default. diff --git src/hg/inc/quickLift.h src/hg/inc/quickLift.h index b3317db9347..334e5d38032 100644 --- src/hg/inc/quickLift.h +++ src/hg/inc/quickLift.h @@ -1,107 +1,112 @@ /* quickLift genome annotations on the fly between assemblies using chain files */ /* Copyright (C) 2023 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #ifndef QUICKLIFT_H #define QUICKLIFT_H #define quickLiftCartName "hubQuickLift" #define quickLiftChainTableConfVariable "quickLiftChainName" #define defaultQuickLiftChainTableName "quickLiftChain" struct quickLiftRegions // store highlight information { struct quickLiftRegions *next; unsigned type; char *chrom; long chromStart; long chromEnd; char *bases; unsigned baseCount; char *oChrom; long oChromStart; long oChromEnd; char *otherBases; unsigned otherBaseCount; char * id; }; #define QUICKTYPE_INSERT 0 #define QUICKTYPE_DEL 1 #define QUICKTYPE_DOUBLE 2 #define QUICKTYPE_MISMATCH 3 extern char *quickTypeStrings[]; typedef struct slList *(*ItemLoader2)(char **row, int numFields); /* Load a bed file from an SQL query result. */ struct bigBedInterval *quickLiftGetIntervals(char *instaPortFile, struct bbiFile *bbi, char *chrom, int start, int end, struct hash **pChainHash); /* Return intervals from "other" species that will map to the current window. * These intervals are NOT YET MAPPED to the current assembly. */ struct bed *quickLiftIntervalsToBed(struct bbiFile *bbi, struct hash *chainHash, struct bigBedInterval *bb); /* Using chains stored in chainHash, port a bigBedInterval from another assembly to a bed * on the reference. */ +struct bed *quickLiftIntervalsToBedClip(struct bbiFile *bbi, struct hash *chainHash, struct bigBedInterval *bb); +/* Like quickLiftIntervalsToBed, but an item too big for the chains we loaded is pulled in + * to what they cover rather than dropped. Callers that need the item's true extent (the + * details page) should use quickLiftIntervalsToBed instead. */ + struct slList *quickLiftSql(struct sqlConnection *conn, char *quickLiftFile, char *table, char *chromName, int winStart, int winEnd, char *query, char *extraWhere, ItemLoader2 loader, int numFields, struct hash *chainHash); /* Load a list of items (usually beds) from another database in a region that corresponds to chromName:winStart-winEnd in the reference database. * Fill a hash with the chains that were used to map the desired range. These chains will be used to map the query side items back to the reference. */ struct genePred *quickLiftGenePreds(struct sqlConnection *conn, char *quickLiftFile, char *table, char *chromName, int winStart, int winEnd, char *extraWhere, struct hash *chainHash); /* Like quickLiftSql, but load genePreds through a genePredReader so the actual set of * (extended) genePred columns in the table is honored rather than assuming 15 columns. * Fill a hash with the chains that were used to map the desired range. */ unsigned quickLiftGetChainId(struct cart *, char *fromDb, char *toDb); /* Return the id from the quickLiftChain table for given assemblies. */ char *quickLiftGetChainPath(struct cart *, char *fromDb, char *toDb); /* Return the path from the quickLiftChain table for given assemblies. */ struct bed *quickLiftBeds(struct bed *bedList, struct hash *chainHash, boolean blocked); // Map a list of bedd in query coordinates to our current reference struct encodePeak *quickLiftPeaks(struct encodePeak *peakList, struct hash *chainHash); // Map a list of encodePeaks in query coordinates to our current reference. These can't go // through quickLiftBeds: the thickStart and thickEnd it assigns overlay signalValue and // pValue in struct encodePeak. boolean quickLiftEnabled(struct cart *cart); /* Return TRUE if feature is available */ struct quickLiftRegions *quickLiftGetRegions(char *ourDb, char *liftDb, char *quickLiftFile, char *chrom, int seqStart, int seqEnd); /* Figure out the highlight regions and cache them. */ char *quickLiftChainTable(); /* Return the name of the quickLiftChain table. */ void quickLiftResolveTable(struct trackDb *tdb, char *trackTable, char **retTable, char **retLiftDb); /* Resolve the table name and liftDb for a quickLift track. For custom tracks, * sets *retLiftDb to CUSTOM_TRASH and *retTable to the dbTableName setting; * otherwise sets *retTable to trackTable. Caller should have already set * *retLiftDb to trackDbSetting(tdb, "quickLiftDb"). */ struct bed *quickLiftSqlLoadBeds(struct trackDb *tdb, char *trackTable, char *liftDb, char *chrom, int start, int end, char *extraWhere, ItemLoader2 loader, int numFields, boolean blocked); /* Load items from another assembly via quickLift SQL, map them back to the reference, * and return the lifted beds. Handles custom track table resolution internally. * Caller provides liftDb from trackDbSetting(tdb, "quickLiftDb"). */ boolean quickLiftLiftPos(char *sourceDb, char *destDb, char *chrom, int start, int end, char **retChrom, int *retStart, int *retEnd); /* Map a position from source (sourceDb) coords to destination (destDb) coords * using the liftOver chain for sourceDb -> destDb. Used to remap hgFind * results from quickLifted bigBed tracks back to the destination assembly. */ boolean quickLiftHubRemoveTrack(struct cart *cart, char *sourceDb, char *trackName); /* Remove a track stanza from the quickLift hub file for sourceDb. Returns * TRUE if a stanza matching trackName was found and removed. */ #endif