2d30d99f5f6d3d6532166a0c70c89d38e6053fb1
braney
  Fri Apr 5 16:57:02 2024 -0700
ongoing work on quickLift

diff --git src/hg/hgConvert/hgConvert.c src/hg/hgConvert/hgConvert.c
index c30b4dc..95e09ca 100644
--- src/hg/hgConvert/hgConvert.c
+++ src/hg/hgConvert/hgConvert.c
@@ -11,30 +11,32 @@
 #include "hCommon.h"
 #include "fa.h"
 #include "cheapcgi.h"
 #include "htmshell.h"
 #include "hdb.h"
 #include "hui.h"
 #include "cart.h"
 #include "web.h"
 #include "chain.h"
 #include "liftOver.h"
 #include "liftOverChain.h"
 #include "chromInfo.h"
 #include "net.h"
 #include "genark.h"
 #include "trackHub.h"
+#include "quickLift.h"
+#include "exportedDataHubs.h"
 
 
 /* CGI Variables */
 #define HGLFT_TOORG_VAR   "hglft_toOrg"           /* TO organism */
 #define HGLFT_TODB_VAR   "hglft_toDb"           /* TO assembly */
 #define HGLFT_DO_CONVERT "hglft_doConvert"	/* Do the actual conversion */
 
 /* Global Variables */
 static struct cart *cart;	        /* CGI and other variables */
 static struct hash *oldVars = NULL;
 static char *organism = NULL;
 static char *database = NULL;
 
 /* Javascript to support New Assembly pulldown when New Genome changes. */
 /* Copies selected values to a hidden form */
@@ -46,67 +48,81 @@
 struct dbDb *db;
 for (db = list; db != NULL; db = db->next)
     {
     if (sameString(name, db->name))
         return db;
     }
 errAbort("Can't find %s in matchingDb", name);
 return NULL;
 }
 
 static void askForDestination(struct liftOverChain *liftOver, char *fromPos,
 	struct dbDb *fromDb, struct dbDb *toDb)
 /* set up page for entering data */
 {
 struct dbDb *dbList;
+boolean askAboutQuickLift = FALSE;
+
+if (exportedDataHubsEnabled())
+    askAboutQuickLift = TRUE;
 
 cartWebStart(cart, database, "Convert %s to New Assembly", fromPos);
 
 /* create HMTL form */
 puts("<FORM ACTION=\"../cgi-bin/hgConvert\" NAME=\"mainForm\">\n");
 cartSaveSession(cart);
 
 /* create HTML table for layout purposes */
 puts("\n<TABLE WIDTH=\"100%%\">\n");
 
 /* top row -- labels */
 cgiSimpleTableRowStart();
 cgiTableField("Old Genome: ");
 cgiTableField("Old Assembly: ");
 cgiTableField("New Genome: ");
 cgiTableField("New Assembly: ");
+if (askAboutQuickLift)
+    cgiTableField("QuickLift Tracks: ");
 cgiTableField(" ");
 cgiTableRowEnd();
 
 /* Next row -- data and controls */
 cgiSimpleTableRowStart();
 
 /* From organism and assembly. */
 cgiTableField(fromDb->organism);
 cgiTableField(fromDb->description);
 
 /* Destination organism. */
 cgiSimpleTableFieldStart();
 dbList = hGetLiftOverToDatabases(liftOver->fromDb);
 printSomeGenomeListHtmlNamed(HGLFT_TOORG_VAR, liftOver->toDb, dbList, "change", onChangeToOrg);
 cgiTableFieldEnd();
 
 /* Destination assembly */
 cgiSimpleTableFieldStart();
 printAllAssemblyListHtmlParm(liftOver->toDb, dbList, HGLFT_TODB_VAR, TRUE, NULL, NULL);
 cgiTableFieldEnd();
 
+if (askAboutQuickLift)
+    {
+    cgiSimpleTableFieldStart();
+    boolean quickLift = cartUsualBoolean(cart, "doQuickLift", FALSE);
+    cgiMakeCheckBoxWithId("doQuickLift", quickLift, "doQuickLift");
+    cgiTableFieldEnd();
+    }
+
 cgiSimpleTableFieldStart();
 cgiMakeButton(HGLFT_DO_CONVERT, "Submit");
 cgiTableFieldEnd();
 
 cgiTableRowEnd();
 cgiTableEnd();
 
 puts("</FORM>\n");
 
 cartWebEnd();
 }
 
 static double scoreLiftOverChain(struct liftOverChain *chain,
     char *fromOrg, char *fromDb, char *toOrg, char *toDb, struct hash *dbRank )
 /* Score the chain in terms of best match for cart settings */
@@ -257,37 +273,56 @@
     }
 slSort(&chainList, chainCmpScore);
 return chainList;
 }
 
 static void doConvert(char *fromPos)
 /* Actually do the conversion */
 {
 struct dbDb *fromDb = hDbDb(trackHubSkipHubName(database)), *toDb = hDbDb(cartString(cart, HGLFT_TODB_VAR));
 char *fileName = liftOverChainFile(fromDb->name, toDb->name);
 fileName = hReplaceGbdbMustDownload(fileName);
 char *chrom;
 int start, end;
 int origSize;
 struct chain *chainList, *chain;
+struct dyString *visDy = NULL;
 
 cartWebStart(cart, database, "%s %s %s to %s %s", fromDb->organism, fromDb->description,
 	fromPos, toDb->organism, toDb->description);
 if (!hgParseChromRange(database, fromPos, &chrom, &start, &end))
     errAbort("position %s is not in chrom:start-end format", fromPos);
 origSize = end - start;
 
+boolean doQuickLift = cartUsualBoolean(cart, "doQuickLift", FALSE);
+
+unsigned quickChain = 0;
+unsigned quickHub = 0;
+
+if (doQuickLift)
+    {
+    quickChain = quickLiftGetChain(fromDb->name, toDb->name);
+
+    if (quickChain == 0)
+        errAbort("can't find quickChain from %s to %s", fromDb->name, toDb->name);
+
+    visDy = newDyString(1024);
+    char *newHub = trackHubBuild(fromDb->name, cart, visDy);
+    if ((quickHub = registerExportedDataHub(fromDb->name, newHub)) == 0)
+        errAbort("can't register exportedDataHub %s\n", newHub);
+    }
+
 chainList = chainLoadAndTrimIntersecting(fileName, chrom, start, end);
 if (chainList == NULL)
     printf("Sorry this position couldn't be found in new assembly");
 else
     {
     for (chain = chainList; chain != NULL; chain = chain->next)
         {
 	int blockSize;
 	int qStart, qEnd;
 	if (chain->qStrand == '-')
 	    {
 	    qStart = chain->qSize - chain->qEnd;
 	    qEnd = chain->qSize - chain->qStart;
 	    }
 	else
@@ -297,40 +332,48 @@
 	    }
 	blockSize = chainTotalBlockSize(chain);
         /* Check if the toDb database exists and if the chromosome
            sequence file (of the hgConvert result) exists in the location
            specified in chromInfo for the toDb. */
 
         boolean chromSeqExists = (sqlDatabaseExists(toDb->name) &&
 				  chromSeqFileExists(toDb->name, chain->qName));
         /* Check if the toDb has active set to 1 in dbDb if the toDb
            database exists.
            If these conditions are met then print position link to
            browser for toDb, otherwise just print position without link. */
         boolean startedAnchor = FALSE;
         if ((hDbIsActive(toDb->name) && chromSeqExists) || startsWith("hub:",toDb->nibPath))
             {
+            if (quickChain)
+                printf("<A HREF=\"%s?db=%s&position=%s:%d-%d&quickLift.%d.%s=%d&hideTracks=1%s\">",
+                   hgTracksName(), toDb->name,  chain->qName, qStart+1, qEnd, quickHub, toDb->name, quickChain, visDy->string);
+            else
                 printf("<A HREF=\"%s?db=%s&position=%s:%d-%d\">",
 		   hgTracksName(), toDb->name, chain->qName, qStart+1, qEnd);
             startedAnchor = TRUE;
             }
         else if (sameString(toDb->nibPath, "genark"))
             {
             char *hubUrl = genarkUrl(toDb->name);
             if (hubUrl)
                 {
                 startedAnchor = TRUE;
+                if (quickChain)
+                    printf("<A HREF=\"%s?genome=%s&hubUrl=%s&position=%s:%d-%d&quickLift.%d.%s=%d\">",
+                       hgTracksName(), toDb->name, hubUrl, chain->qName, qStart+1, qEnd, quickHub, toDb->name, quickChain);
+                else
                     printf("<A HREF=\"%s?genome=%s&hubUrl=%s&position=%s:%d-%d\">",
                        hgTracksName(), toDb->name, hubUrl, chain->qName, qStart+1, qEnd);
                 }
             }
 	printf("%s:%d-%d",  chain->qName, qStart+1, qEnd);
         if (startedAnchor)
 	    printf("</A>");
 	printf(" (%3.1f%% of bases, %3.1f%% of span)<BR>\n",
 	    100.0 * blockSize/origSize,
 	    100.0 * (chain->tEnd - chain->tStart) / origSize);
 	}
     }
 cartWebEnd();
 }