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/liftOver.h src/hg/inc/liftOver.h index d849fff3fe2..f293a83045e 100644 --- src/hg/inc/liftOver.h +++ src/hg/inc/liftOver.h @@ -1,147 +1,151 @@ /* lift genome annotations between assemblies using chain files */ /* Copyright (C) 2013 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #ifndef LIFTOVER_H #define LIFTOVER_H #include "chain.h" #include "genePred.h" #define LIFTOVER_MINMATCH 0.95 #define LIFTOVER_MINBLOCKS 1.00 #define liftOverChainTableConfVariable "liftOverChainName" #define defaultLiftOverChainTableName "liftOverChain" enum liftOverFileType { none = 0, bed = 1, positions = 2, }; struct liftOverChain *liftOverChainList(); /* Get list of all liftOver chains in the central database */ void filterOutMissingChains(struct liftOverChain **pChainList); /* Filter out chains that don't exist. Helps partially mirrored sites. */ struct liftOverChain *liftOverChainListFiltered(); /* Get list of all liftOver chains in the central database * filtered to include only those chains whose liftover files exist. * This helps partially mirrored sites */ struct liftOverChain *liftOverChainForDb(char *fromDb); /* Return list of liftOverChains for this database. */ struct liftOverChain *liftOverChainListForDbFiltered(char *fromDb); /* Get list of all liftOver chains in the central database for fromDb, * filtered to include only those chains whose liftover files exist. */ char *liftOverChainFile(char *fromDb, char *toDb); /* Get filename of liftOver chain */ enum liftOverFileType liftOverSniff(char *fileName); /* the file-sniffing bit used to distinguish bed from positions files */ /* returns enum concerning the file type */ int liftOverBed(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, int minSizeT, int minSizeQ, int minChainT, int minChainQ, bool fudgeThick, FILE *f, FILE *unmapped, bool multiple, bool noSerial, char *chainTable, int *errCt, bool preserveInput); /* Open up file, decide what type of bed it is, and lift it. * Return the number of records successfully converted */ int liftOverBedPlus(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, int minSizeT, int minSizeQ, int minChainT, int minChainQ, bool fudgeThick, FILE *f, FILE *unmapped, bool multiple, bool noSerial, char *chainTable, int bedPlus, bool hasBin, bool tabSep, int *errCt, bool preserveInput); /* Lift bed with N+ (where n=bedPlus param) format. * Return the number of records successfully converted */ int liftOverBedPlusEnds(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, int minSizeT, int minSizeQ, int minChainT, int minChainQ, bool fudgeThick, FILE *f, FILE *unmapped, bool multiple, bool noSerial, char *chainTable, int bedPlus, bool hasBin, bool tabSep, int ends, int *errCt, bool preserveInput); /* Lift bed N+ file. * Return the number of records successfully converted */ int liftOverPositions(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, int minSizeT, int minSizeQ, int minChainT, int minChainQ, bool fudgeThick, FILE *f, FILE *unmapped, bool multiple, char *chainTable, int *errCt); /* Create bed file from positions (chrom:start-end) and lift. * Return the number of records successfully converted */ int liftOverBedOrPositions(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, int minSizeT, int minSizeQ, int minChainT, int minChainQ, bool fudgeThick, FILE *mapped, FILE *unmapped, bool multiple, bool noSerial, char *chainTable, int *errCt); /* Sniff the first line of the file, and determine whether it's a */ /* bed, a positions file, or neither. */ char *liftOverRemapRange(struct hash *chainHash, double minRatio, char *chrom, int s, int e, char strand, double minMatch, char **retChrom, int *retStart, int *retEnd, char *retStrand); /* Remap a range through chain hash. If all is well return NULL * and results in retChrom, retStart, retEnd. Otherwise * return a string describing the problem. */ void liftOverGff(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, FILE *mapped, FILE *unmapped, bool preserveInput); /* Lift over GFF file */ void liftOverPsl(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, bool fudgeThick, FILE *f, FILE *unmapped); /* Open up PSL file, and lift it. */ void liftOverGenePred(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, bool fudgeThick, FILE *mapped, FILE *unmapped, boolean multiple, bool preserveInput); /* Lift over file in genePred format. */ void calcLiftOverGenePreds( struct genePred *gpList, struct hash *chainHash, double minMatch, double minBlocks, bool fudgeThick, FILE *mapped, FILE *unmapped, boolean multiple, bool preserveInput); /* worker function for liftOverGenePred. */ void liftOverSample(char *fileName, struct hash *chainHash, double minMatch, double minBlocks, bool fudgeThick, FILE *mapped, FILE *unmapped, bool preserveInput); /* Open up sample file, and lift it */ void readLiftOverMap(char *fileName, struct hash *chainHash); /* Read map file into hashes. */ char *liftOverErrHelp(); /* Help message explaining liftOver failures */ char *remapBlockedBed(struct hash *chainHash, struct bed *bed, double minMatch, double minBlocks, bool fudgeThick, bool multiple, char *db, char *chainTable); /* Remap blocks in bed, and also chromStart/chromEnd. If multiple, then bed->next may be * changed to point to additional newly allocated mapped beds, and bed's pointer members may * be free'd so be sure to pass in a properly allocated bed. * Return NULL on success, an error string on failure. */ void liftOverAddChainHash(struct hash *chainHash, struct chain *chain); /* Add this chain to the hash of chains used by remapBlockedBed */ +struct chain *liftOverChainForRange(struct hash *chainHash, char *chrom, int start, int end); +/* Return the chain in chainHash covering the most aligned bases in the given range, + * or NULL if none overlap it. This is the chain remapBlockedBed would also pick. */ + char *liftOverChainTable(); /* Return the name of the liftOverChain table. */ #endif