cb9de88c1e416860a1a69047f6e4c9b338a1cfec
braney
  Tue Jul 18 17:22:47 2023 -0700
first cut at liftOver on the fly

diff --git src/hg/lib/chainNetDbLoad.c src/hg/lib/chainNetDbLoad.c
index 1528c2f..9da17aa 100644
--- src/hg/lib/chainNetDbLoad.c
+++ src/hg/lib/chainNetDbLoad.c
@@ -217,93 +217,91 @@
     slAddHead(&list, b);
     }
 slSort(&list, cBlockCmpTarget);
 chain->blockList = list;
 }
 
 struct chain *chainLoadIdRangeHub(char *db, char *fileName, char *linkFileName,   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 lm *lm = lmInit(0);
 struct bbiFile *bbi =  bigBedFileOpenAlias(fileName, chromAliasFindAliases);
 struct bigBedInterval *bb, *bbList =  bigBedIntervalQuery(bbi, chrom, start, end, 0, lm);
+struct bbiFile *linkBbi =  bigBedFileOpenAlias(linkFileName, chromAliasFindAliases);
+struct bigBedInterval *linkBb, *linkBbList =  bigBedIntervalQuery(linkBbi, chrom, start, end, 0, lm);
 char *bedRow[12];
 char startBuf[16], endBuf[16];
-bbiFileClose(&bbi);
-boolean loadAll = FALSE;
 
+struct chain *chainList = NULL;
 struct chain *chain;
-AllocVar(chain);
 
 for (bb = bbList; bb != NULL; bb = bb->next)
     {
     bigBedIntervalToRow(bb, chrom, startBuf, endBuf, bedRow, ArraySize(bedRow));
 
     unsigned chainId = sqlUnsigned(bedRow[3]);
-    if (chainId == id)
-        break;
-    }
-
-if (bb == NULL)
-    errAbort("chain %d is not in %s", id, fileName);
+    if ((chainId == id) || (id == -1))
+        {
+        AllocVar(chain);
 
         chain->tName = cloneString(chrom);
         chain->tSize = sqlUnsigned(bedRow[6]);
         chain->tStart = sqlUnsigned(bedRow[1]);
         chain->tEnd = sqlUnsigned(bedRow[2]);
         chain->qName = cloneString(bedRow[7]);
         chain->qSize = sqlUnsigned(bedRow[8]);
         chain->qStrand = *bedRow[5];
         chain->qStart = sqlUnsigned(bedRow[9]);
         chain->qEnd = sqlUnsigned(bedRow[10]);
         chain->score = sqlUnsigned(bedRow[11]);
-chain->id = id;
+        chain->id = chainId;
 
-// Now load the links.
-bbi =  bigBedFileOpenAlias(linkFileName, chromAliasFindAliases);
-if (loadAll)
+        for (linkBb = linkBbList; linkBb != NULL; linkBb = linkBb->next)
             {
-    start = chain->tStart;
-    end = chain->tEnd;
-    }
-bbList =  bigBedIntervalQuery(bbi, chrom, start, end, 0, lm);
-bbiFileClose(&bbi);
-
-for (bb = bbList; bb != NULL; bb = bb->next)
-    {
-    bigBedIntervalToRow(bb, chrom, startBuf, endBuf, bedRow, ArraySize(bedRow));
+            bigBedIntervalToRow(linkBb, chrom, startBuf, endBuf, bedRow, ArraySize(bedRow));
             unsigned chainId = sqlUnsigned(bedRow[3]);
-    if (chainId == id)
+            if (chainId == chain->id)
                 {
                 struct cBlock *cBlock;
 
                 AllocVar(cBlock);
                 slAddHead(&chain->blockList, cBlock);
                 cBlock->tStart = sqlUnsigned(bedRow[1]);
                 cBlock->tEnd = sqlUnsigned(bedRow[2]);
                 unsigned size = cBlock->tEnd - cBlock->tStart;
                 cBlock->qStart = sqlUnsigned(bedRow[4]);
                 cBlock->qEnd = cBlock->qStart + size;
                 }
             }
         slReverse(&chain->blockList);
 
+        slAddHead(&chainList, chain);
+
+        if (id > 0)  // bail out if we found the id we were looking for
+            break;
+        }
+    }
+
+bbiFileClose(&bbi);
+bbiFileClose(&linkBbi);
 lmCleanup(&lm);
-return chain;
+if ((id > 0) && (bb == NULL))
+    errAbort("chain %d is not in %s", id, fileName);
+return chainList;
 }
 
 static struct chain *chainLoadIdSome(char *database, char *track, char *chrom, 
         int start, int end, int id, boolean loadAll)
 /* Load some or all of chain. */
 {
 struct sqlConnection *conn;
 struct sqlResult *sr;
 char **row;
 char table[HDB_MAX_TABLE_STRING];
 boolean hasBin;
 struct chain *chain;
 char query[256];
 struct dyString *dy = dyStringNew(128);