f29b65452a1cca8a5bc62f007100b313e589d036
braney
  Sun Sep 6 15:11:36 2026 -0700
quickLift: lift a bigNet track, refs #20824

A net is not an ordinary track to lift.  It is an alignment of two assemblies,
so only its target side moves to the new reference; the query side names a third
assembly and is carried across untouched.  And the browser draws a net by
recursion, so what really has to survive the lift is the tree: a row's level only
means anything relative to the row above it.

chainNetLoadRangeQuickLift() maps each row's target range with
quickLiftIntervalsToBedClip, which is the same code every other quickLift track
uses, so a net row lands where a bed of the same span would.  The surviving rows
then go to the same helpToNet() the unlifted path uses, so there is one tree
builder and not two.  The row collection either path does is now cnlHelperNew and
cnlHelperAddBigNet.

validateOneTdb lets bigNet into a quickLift hub.  Its chain track is not offered,
so a lifted net's details page has no chain to follow and says so rather than
looking for a track this assembly does not have.  bigNetLoadOne lifts the same
way for that page, unclipped, so it reports the item's whole extent.

bigNetFromInterval passes -1 as the cached chromId.  bbiCachedChromLookup leaves
the buffer alone when the id matches the one before it, so a cache that outlives
the buffer hands back stale bytes.

Measured against the standalone liftOver tool, on hg19 chr22's mouse net lifted
to hg38: 36 of 36 source rows in the sampled window land on the same coordinates,
counting the one liftOver will not take whole, whose two ends it does place
exactly where the browser puts them.  Against hg38's own mouse net, computed
independently, 1.02% of the drawn pixels differ.

diff --git src/hg/inc/chainNetDbLoad.h src/hg/inc/chainNetDbLoad.h
index 2550b2fcd02..b15d327505e 100644
--- src/hg/inc/chainNetDbLoad.h
+++ src/hg/inc/chainNetDbLoad.h
@@ -1,63 +1,79 @@
 /* chainNetDbLoad - This will load a database representation of
  * a net into a chainNet representation.  Also helps database
  * representation of chain into chain. */
 
 /* Copyright (C) 2002 The Regents of the University of California 
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 
 #ifndef CHAINNETDBLOAD_H
 #define CHAINNETDBLOAD_H
 
 #ifndef JKSQL_H
 #include "jksql.h"
 #endif
 
 #ifndef NETALIGN_H
 #include "netAlign.h"
 #endif
 
 #ifndef CHAINNET_H
 #include "chainNet.h"
 #endif
 
+#ifndef BIGNET_H
+#include "bigNet.h"
+#endif
+
 
 struct cnFill *cnFillFromNetAlign(struct netAlign *na, struct hash *nameHash);
 /* Convert netAlign to cnFill. Name hash is a place to store
  * the strings. */
 
 struct chainNet *chainNetLoadResult(struct sqlResult *sr, int rowOffset);
 /* Given a query result that returns a bunch netAligns, make up
  * a list of chainNets that has the equivalent information. 
  * Note the net->size field is not filled in. */
 
 struct chainNet *chainNetLoadRange(char *database, char *track,
 	char *chrom, int start, int end, char *extraWhere);
 /* Load parts of a net track that intersect range. */
 
 struct chainNet *chainNetLoadRangeHub(char *fileName, char *chrom, int start, int end);
 /* Load the parts of a bigNet file that intersect range into a chainNet.
  * Note the net->size field is not filled in. */
 
+struct chainNet *chainNetLoadRangeQuickLift(char *quickLiftFile, char *fileName,
+                                            char *chrom, int start, int end);
+/* Load the part of a bigNet file that quickLifts into chrom:start-end, and build a
+ * chainNet in the destination assembly's coordinates.  Only the target side of the net
+ * moves; the query side describes a third assembly and is carried across untouched.
+ * Note the net->size field is not filled in. */
+
+struct bigNet *bigNetFromInterval(struct bbiFile *bbi, struct bigBedInterval *bb,
+                                  char *fileName, struct bigNet *bn);
+/* Fill in bn from one interval of a bigNet file.  The chrom name is the one the file
+ * carries, which for a quickLifted net is in the source assembly. */
+
 struct chainNet *chainNetLoadChrom(char *database, char *track,
 	char *chrom, char *extraWhere);
 /* Load net on whole chromosome. */
 
 struct chain *chainLoadIdRangeHub(char *database, char *fileName, char *track, char *chrom, 
 	int start, int end, int id);
 /* Load parts of chain of given ID from bigChain file.  Note the chain header
  * including score, tStart, tEnd, will still reflect the whole chain,
  * not just the part in range.  However only the blocks of the chain
  * overlapping the range will be loaded. */
 
 struct chain *chainLoadIdRange(char *database, char *track, char *chrom, 
 	int start, int end, int id);
 /* Load parts of chain of given ID from database.  Note the chain header
  * including score, tStart, tEnd, will still reflect the whole chain,
  * not just the part in range.  However only the blocks of the chain
  * overlapping the range will be loaded. */
 
 struct chain *chainLoadId(char *database, char *track, char *chrom, int id);
 /* Load chain of given ID from database. */
 
 #endif /* CHAINNETDBLOAD_H */