e70c7f68f61a3477631bd364c31f99c157528fc8 braney Fri Sep 4 12:48:02 2026 -0700 quickLift: lift chains, and let chain and bigChain tracks into the hub A chain is an alignment between the assembly the track came from and some other species, so lifting one composes two alignments and leaves the user with chains between the assembly on screen and that species. quickLiftChain does it by the same route the psl work uses: chainToPsl, then quickLiftPsl, then chainFromPsl, which is the inverse chainToPsl never had. It does not modify the chain handed to it. That matters more than it sounds: every chain loader leaves the header describing the whole chain while loading only the blocks in range, so the header has to be corrected for the conversion, but the callers still want the original. The details page reports it, and the track sorts on it, which is what puts a lifted chain in the same row as the native one. quickLiftSourceRanges hands back the ranges in the other assembly that the window maps to, for callers whose items cannot be had from a query quickLiftSql knows how to make. It works those ranges out by intersecting the window with each chain block rather than taking the whole block, which matters here because one block can be enormous: hg19 and hg38 run identical for 12.8Mb on chr7, and asking for all of it turned a 39 chain window into a 1892 chain one. quickLiftIsOwnChainTrack keeps quickLift's own chain track out of all this. That stanza carries quickLiftUrl and quickLiftDb like any lifted track and is loaded by bigChainLoadItems like any bigChain, but its data is already in reference coordinates. The giveaway is that its bigDataUrl is the quickLift chain file. validateOneTdb now accepts chain and bigChain. netAlign is still refused: a net is a hierarchy of gaps rather than a plain alignment and wants its own thought. refs #38249 diff --git src/hg/inc/quickLift.h src/hg/inc/quickLift.h index 0769d75661f..06c0ef4abd6 100644 --- src/hg/inc/quickLift.h +++ src/hg/inc/quickLift.h @@ -1,29 +1,30 @@ /* 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 psl; +struct chain; 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; @@ -62,42 +63,69 @@ 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 quickLiftRange +// A range in the other assembly that some part of the reference window maps back to. +{ +struct quickLiftRange *next; +char *chrom; /* sequence name in the other assembly */ +int start; +int end; +}; + +struct quickLiftRange *quickLiftSourceRanges(char *quickLiftFile, char *chrom, int start, int end, + struct hash *chainHash); +// The ranges in the other assembly that map into chrom:start-end on the reference. The +// chains that do the mapping are added to chainHash, which is the form the lift functions +// read. Use this when the items cannot be had from a query quickLiftSql knows how to make. + struct hash *quickLiftChainHash(char *quickLiftFile, char *chrom, int start, int end); // Load the quickLift chains covering chrom:start-end on the reference and return them in a // hash keyed on the other assembly's sequence names, which is the shape the lift functions // want. Use this when the items were fetched some other way, so quickLiftSql was not the // thing that collected the chains. struct psl *quickLiftPsl(struct hash *chainHash, struct hash **pMapPsls, struct psl *psl); // Map the target side of an alignment from the other assembly onto our current reference. // The query side (the mRNA, EST or protein the alignment is to) is left alone. Returns // NULL if the alignment doesn't map. pMapPsls points at a hash of mapping alignments the // caller keeps across a run of items; point it at a NULL hash to start. +boolean quickLiftIsOwnChainTrack(struct trackDb *tdb); +// TRUE when this is the chain track quickLift builds to show the lift itself. That stanza +// carries quickLiftUrl and quickLiftDb like any lifted track, but its data is already in +// reference coordinates and must not be lifted a second time. + +struct chain *quickLiftChain(struct hash *chainHash, struct hash **pMapPsls, + struct chain *chain); +// Map a chain's target side from the other assembly onto our current reference. A chain is +// an alignment between that assembly and some other species, so this composes the two and +// leaves a chain between the reference and that species. The query side is left alone. +// Returns NULL if the chain doesn't map. The chain handed in is not modified. + struct psl *quickLiftPsls(struct hash *chainHash, struct psl *pslList); // Map a list of alignments in the other assembly's coordinates onto our current reference. // Alignments that don't map are dropped. 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. */