b407a64ccfcc6ca94abf79593ff90e515c4dbc1c
angie
  Tue Sep 3 10:20:24 2013 -0700
hgVai can now handle assembly hubs, but if they have no genePred tracks, itcan't really do anything useful so it just suggests that the user choose a different assembly.
fixes #11306

diff --git src/hg/hgVai/hgVai.c src/hg/hgVai/hgVai.c
index 18c2618..66c3f23 100644
--- src/hg/hgVai/hgVai.c
+++ src/hg/hgVai/hgVai.c
@@ -114,32 +114,30 @@
 }
 
 INLINE void printOption(char *val, char *selectedVal, char *label)
 /* For rolling our own select without having to build conditional arrays/lists. */
 {
 printf("<OPTION VALUE='%s'%s>%s\n", val, (sameString(selectedVal, val) ? " SELECTED" : ""), label);
 }
 
 void printRegionListHtml(char *db)
 /* Make a dropdown choice of region type, with position input box that appears if needed.
  * Unlike hgTables, don't bother with ENCODE pilot regions -- unless someone misses it.
  * Return the selected region type. */
 {
 printf("<SELECT ID='"hgvaRegionType"' NAME='"hgvaRegionType"' "
        "onchange=\"hgva.changeRegion();\">\n");
-struct sqlConnection *conn = hAllocConn(db);
-hFreeConn(&conn);
 printOption(hgvaRegionTypeGenome, regionType, "genome");
 printOption(hgvaRegionTypeRange, regionType, "position or search term");
 printf("</SELECT>");
 }
 
 void topLabelSpansStart(char *label)
 {
 printf("<span style='display: inline-block; padding-right: 5px;'>"
        "<span style='display: block;'>%s</span>\n"
        "<span style='display: block; padding-bottom: 5px;'>\n", label);
 }
 
 void topLabelSpansEnd()
 {
 printf("</span></span>");
@@ -339,54 +337,68 @@
 char *curLimit = cartUsualString(cart, "hgva_variantLimit", "10000");
 char *limitLabels[] = { "10", "100", "1,000", "10,000", "100,000" };
 char *limitValues[] = { "10", "100", "1000", "10000", "100000" };
 cgiMakeDropListWithVals("hgva_variantLimit", limitLabels, limitValues, ArraySize(limitLabels),
 			curLimit);
 printCtAndHubButtons();
 puts("<BR>");
 }
 
 boolean isGeneTrack(struct trackDb *tdb, void *filterData)
 /* This is a TdbFilterFunction to get genePred tracks. */
 {
 return (startsWith("genePred", tdb->type));
 }
 
-void selectGenes()
-/* Let user select a gene predictions track */
+boolean selectGenes()
+/* Let user select a gene predictions track; return FALSE if there are no genePred tracks. */
 {
 struct slRef *trackRefList = NULL;
 tdbFilterGroupTrack(fullTrackList, fullGroupList, isGeneTrack, NULL, NULL, &trackRefList);
-if (trackRefList == NULL)
-    return;
+boolean gotGP = (trackRefList != NULL);
+if (!gotGP)
+    warn("This assembly (%s) has no gene prediction tracks, "
+	 "so the VAI will not be able to annotate it.", database);
 printf("<div class='sectionLiteHeader'>Select Genes</div>\n");
-printf("The gene predictions selected here will be used to determine the effect of "
-       "each variant on genes, for example intronic, missense, splice site, intergenic etc."
-       "<BR>\n");
+if (gotGP)
+    printf("The gene predictions selected here will be used ");
+else
+    printf("Gene predictions are required in order ");
+printf("to determine the effect of "
+       "each variant on genes, for example intronic, missense, splice site, intergenic etc.");
+if (!gotGP)
+    printf(" Since this assembly has no gene prediction tracks, "
+	   "the VAI can't provide functional annotations. "
+	   "Please select a different genome.<BR>");
+printf("<BR>\n");
 char *selected = cartUsualString(cart, "hgva_geneTrack", ""); //#*** per-db cart vars??
 //#*** should show more info about each track... button to pop up track desc?
 
+if (gotGP)
+    {
     printf("<SELECT ID='hgva_geneTrack' NAME='hgva_geneTrack'>\n");
     struct slRef *ref;
     for (ref = trackRefList;  ref != NULL;  ref = ref->next)
 	{
 	struct trackDb *tdb = ref->val;
     if (tdb->subtracks == NULL)
 	printOption(tdb->track, selected, tdb->longLabel);
 	}
     puts("</SELECT><BR>");
     }
+return gotGP;
+}
 
 //#*** We really need a dbNsfp.[ch]:
 enum PolyPhen2Subset { noSubset, HDIV, HVAR };
 
 char *formatDesc(char *url, char *name, char *details, boolean doHtml)
 /* Return a description with URL for name plus extra details.  If doHtml,
  * wrap URL in <A ...>...</A>. */
 {
 char desc[1024];
 if (doHtml)
     safef(desc, sizeof(desc), "<A HREF='%s' TARGET=_BLANK>%s</A> %s",
 	  url, name, details);
 else
     safef(desc, sizeof(desc), "(%s) %s %s",
 	  url, name, details);
@@ -425,30 +437,32 @@
 			  "(D = deleterious, N = Neutral, U = unknown)", doHtml);
 else if (sameString(tableName, "dbNsfpGerpNr"))
 	return formatDesc("http://mendel.stanford.edu/SidowLab/downloads/gerp/index.html",
 			  "GERP++", "Neutral Rate (NR)", doHtml);
 else if (sameString(tableName, "dbNsfpGerpRs"))
 	return formatDesc("http://mendel.stanford.edu/SidowLab/downloads/gerp/index.html",
 			  "GERP++", "Rejected Substitutions (RS)", doHtml);
 else if (sameString(tableName, "dbNsfpInterPro"))
 	return formatDesc("http://www.ebi.ac.uk/interpro/", "InterPro", "protein domains", doHtml);
 return NULL;
 }
 
 struct slName *findDbNsfpTables()
 /* See if this database contains dbNSFP tables. */
 {
+if (startsWith(hubTrackPrefix, database))
+    return NULL;
 struct sqlConnection *conn = hAllocConn(database);
 struct slName *dbNsfpTables = sqlQuickList(conn, "NOSQLINJ show tables like 'dbNsfp%'");
 hFreeConn(&conn);
 return dbNsfpTables;
 }
 
 void printDbNsfpSource(char *table, enum PolyPhen2Subset subset)
 /* If we know what to do with table, make a checkbox with descriptive label. */
 {
 char *description = dbNsfpDescFromTableName(table, subset, TRUE);
 if (description != NULL)
     {
     char cartVar[512];
     if (subset == HDIV)
 	safef(cartVar, sizeof(cartVar), "hgva_track_%s_%s:HDIV", database, table);
@@ -492,30 +506,32 @@
 	printDbNsfpSource(table->name, HDIV);
 	printDbNsfpSource(table->name, HVAR);
 	}
     else
 	printDbNsfpSource(table->name, 0);
     }
 puts("<BR>");
 endCollapsibleSection();
 }
 
 boolean findSnpBed4(char *suffix, char **retFileName, struct trackDb **retTdb)
 /* If we can find the latest snpNNNsuffix track using 'show tables rlike "regex"',
  * or better yet a bigBed file for it (faster),
  * set the appropriate ret* and return TRUE, otherwise return FALSE. */
 {
+if (startsWith(hubTrackPrefix, database))
+    return FALSE;
 if (suffix == NULL)
     suffix = "";
 char query[64];
 sqlSafef(query, sizeof(query), "show tables like 'snp1__%s'", suffix);
 struct sqlConnection *conn = hAllocConn(database);
 struct slName *snpNNNTables = sqlQuickList(conn, query);
 hFreeConn(&conn);
 if (snpNNNTables == NULL)
     return FALSE;
 boolean foundIt = FALSE;
 // Skip to last in list -- highest number (show tables can't use rlike or 'order by'):
 struct slName *table = snpNNNTables;
 while (table->next != NULL && isdigit(table->next->name[4]) && isdigit(table->next->name[5]))
     table = table->next;
 // Do we happen to have a bigBed version?  Better yet, bed4 only for current uses:
@@ -807,46 +823,48 @@
 jsIncludeFile("jquery-ui.js", NULL);
 webIncludeResourceFile("jquery-ui.css");
 jsIncludeFile("hgVarAnnogrator.js", NULL);
 boolean alreadyAgreed = cartUsualBoolean(cart, "hgva_agreedToDisclaimer", FALSE);
 printf("<script>\n"
        "$(document).ready(function() { hgva.disclaimer.init(%s, hgva.userClickedAgree); });\n"
        "</script>\n", alreadyAgreed ? "true" : "false");
 addSomeCss();
 printAssemblySection();
 
 /* Check for variant custom tracks.  If there are none, tell user they need to
  * upload at least one. */
 struct slRef *varTrackList = NULL, *varGroupList = NULL;
 tdbFilterGroupTrack(fullTrackList, fullGroupList, isVariantCustomTrack, NULL,
 		    &varGroupList, &varTrackList);
-
 if (varTrackList == NULL)
     {
     askUserForVariantCustomTrack();
     }
 else
     {
     puts("<BR>");
     // Make wrapper table for collapsible sections:
     selectVariants(varGroupList, varTrackList);
-    selectGenes();
+    boolean gotGP = selectGenes();
+    if (gotGP)
+	{
 	selectAnnotations();
 	selectFilters();
 	selectOutput();
 	submitAndDisclaimer();
 	}
+    }
 printf("</FORM>");
 
 jsReloadOnBackButton(cart);
 
 webNewSection("Using the Variant Annotation Integrator");
 webIncludeHelpFile("hgVaiHelpText", FALSE);
 }
 
 void doUi()
 /* Set up globals and make web page */
 {
 cartWebStart(cart, database, "Variant Annotation Integrator");
 doMainPage();
 cartWebEnd();
 /* Save variables. */
@@ -1241,32 +1259,30 @@
 if (hIsPrivateHost())
     pushCarefulMemHandler(LIMIT_2or6GB);
 htmlPushEarlyHandlers(); /* Make errors legible during initialization. */
 
 cgiSpoof(&argc, argv);
 oldVars = hashNew(10);
 setUdcCacheDir();
 boolean startQuery = (cgiUsualString("hgva_startQuery", NULL) != NULL);
 if (startQuery)
     cart = cartAndCookieNoContent(hUserCookie(), excludeVars, oldVars);
 else
     cart = cartAndCookie(hUserCookie(), excludeVars, oldVars);
 
 /* Set up global variables. */
 getDbAndGenome(cart, &database, &genome, oldVars);
-if (trackHubDatabase(database))
-    errAbort("Assembly Data Hubs not yet supported by the Variant Annotaion Integrator");
 regionType = cartUsualString(cart, hgvaRegionType, hgvaRegionTypeGenome);
 if (isEmpty(cartOptionalString(cart, hgvaRange)))
     cartSetString(cart, hgvaRange, hDefaultPos(database));
 
 int timeout = cartUsualInt(cart, "udcTimeout", 300);
 if (udcCacheTimeout() < timeout)
     udcSetCacheTimeout(timeout);
 #if ((defined USE_BAM || defined USE_TABIX) && defined KNETFILE_HOOKS)
 knetUdcInstall();
 #endif//def (USE_BAM || USE_TABIX) && KNETFILE_HOOKS
 
 initGroupsTracksTables(cart, &fullTrackList, &fullGroupList);
 if (lookupPosition(cart, hgvaRange))
     {
     if (startQuery)