50bf71bc5c57303fb4d7225283f48cd13ba41bcf
angie
  Wed Nov 18 23:20:57 2015 -0800
Change to interface of annoStreamDbNew: instead of making the caller
pass in an asObject, the caller may now pass in a parsed JSON config
object (or NULL).  annoStreamDbNew will use this config object to
determine whether related tables need to be joined with the track table,
and produce its own asObj.  It doesn't actually do that yet -- this
is just an interface change that will enable it to do so.
refs #15544

diff --git src/hg/hgVai/hgVai.c src/hg/hgVai/hgVai.c
index 3378f46..f21c85f 100644
--- src/hg/hgVai/hgVai.c
+++ src/hg/hgVai/hgVai.c
@@ -1182,31 +1182,31 @@
     grator = hashFindVal(gratorsByName, tdb->table);
     if (retDescription)
 	*retDescription = cloneString(tdb->longLabel);
     }
 if (grator != NULL)
     {
     // Set its overlap behavior and we're done.
     grator->setOverlapRule(grator, overlapRule);
     return grator;
     }
 // If not in gratorsByName, then attempt to construct it here:
 if (fileName != NULL)
     grator = hAnnoGratorFromBigFileUrl(fileName, assembly, ANNO_NO_LIMIT, overlapRule);
 else
     grator = hAnnoGratorFromTrackDb(assembly, tdb->table, tdb, chrom, ANNO_NO_LIMIT,
-                                    NULL, overlapRule);
+                                    NULL, overlapRule, NULL);
 if (grator != NULL)
     hashAdd(gratorsByName, tdb->table, grator);
 return grator;
 }
 
 char *tableNameFromSourceName(char *sourceName)
 /* Strip sourceName (file path or db.table) to just the basename or table name. */
 {
 char *tableName = cloneString(sourceName);
 char *p = strrchr(tableName, '/');
 if (p != NULL)
     {
     // file path; strip to basename
     char dir[PATH_LEN], name[FILENAME_LEN], extension[FILEEXT_LEN];
     splitPath(tableName, dir, name, extension);
@@ -1442,31 +1442,31 @@
 	{
 	// trackName for PolyPhen2 has a suffix for subset -- strip it if we find it:
 	subset = stripSubsetFromTrackName(trackName);
 	description = dbNsfpDescFromTableName(trackName, subset, doHtml);
 	addDbNsfpSeqChange(trackName, assembly, gratorsByName, pGratorList);
 	char *fileName = fileNameFromTable(trackName);
 	if (fileName != NULL)
 	    grator = hAnnoGratorFromBigFileUrl(fileName, assembly, ANNO_NO_LIMIT, agoNoConstraint);
 	}
     else
 	{
 	struct trackDb *tdb = tdbForTrack(database, trackName, &fullTrackList);
 	if (tdb != NULL)
 	    {
 	    grator = hAnnoGratorFromTrackDb(assembly, tdb->table, tdb, chrom, ANNO_NO_LIMIT, NULL,
-                                            agoNoConstraint);
+                                            agoNoConstraint, NULL);
 	    if (grator != NULL)
 		{
 		//#*** Need something more sophisticated but this works for our
 		//#*** limited selection of extra tracks:
 		if (asColumnFind(grator->streamer.asObj, "name") != NULL)
 		    column = "name";
 		addFiltersToGrator(grator, tdb);
 		}
 	    description = tdb->longLabel;
 	    isReg = (includeReg &&
                      ((sameString(database, "hg19") && isHg19RegulatoryTrack(tdb, NULL)) ||
                       (sameString(database, "hg38") && isHg38RegulatoryTrack(tdb, NULL))));
 	    }
 	}
     haveReg |= isReg;
@@ -1493,31 +1493,31 @@
     {
     struct annoGrator *grator = gratorForSnpBed4(gratorsByName, "Mult", assembly, chrom,
 						 agoMustNotOverlap, NULL);
     updateGratorList(grator, pGratorList);
     }
 
 if (cartUsualBoolean(cart, "hgva_require_consEl", FALSE))
     {
     char *consElTrack = cartString(cart, "hgva_require_consEl_track");
     struct annoGrator *grator = hashFindVal(gratorsByName, consElTrack);
     if (grator == NULL)
 	{
 	struct trackDb *tdb = tdbForTrack(database, consElTrack, &fullTrackList);
 	if (tdb != NULL)
 	    grator = hAnnoGratorFromTrackDb(assembly, tdb->table, tdb, chrom, ANNO_NO_LIMIT, NULL,
-                                            agoMustOverlap);
+                                            agoMustOverlap, NULL);
 	updateGratorList(grator, pGratorList);
 	}
     else
 	grator->setOverlapRule(grator, agoMustOverlap);
     }
 }
 
 static void getCartPosOrDie(char **retChrom, uint *retStart, uint *retEnd)
 /* Get chrom:start-end from cart, errAbort if any problems. */
 {
 char *position = cartString(cart, hgvaRange);
 if (! parsePosition(position, retChrom, retStart, retEnd))
     errAbort("Expected position to be chrom:start-end but got '%s'", position);
 }
 
@@ -1740,31 +1740,31 @@
 }
 
 // margin for intergenic variants around transcript:
 #define IGFUDGE 5
 
 static struct annoStreamer *makeSampleVariantsStreamer(struct annoAssembly *assembly,
 						       struct trackDb *geneTdb, int maxOutRows)
 /* Construct a VCF file of example variants for db (unless it already exists)
  * and return an annoStreamer for that file.  If possible, make the variants hit a gene. */
 {
 char *sampleFile = sampleVariantsPath(assembly, geneTdb->track);
 boolean forceRebuild = cartUsualBoolean(cart, "hgva_rebuildSampleVariants", FALSE);
 if (! fileExists(sampleFile) || forceRebuild)
     {
     struct annoStreamer *geneStream = hAnnoStreamerFromTrackDb(assembly, geneTdb->table, geneTdb,
-                                                               NULL, ANNO_NO_LIMIT);
+                                                               NULL, ANNO_NO_LIMIT, NULL);
     boolean isBig = sameString(geneTdb->type, "bigGenePred");
     boolean gotCoding = FALSE, gotNonCoding = FALSE;
     struct genePred *gpList = genesFromPosition(geneStream, isBig, &gotCoding, &gotNonCoding);
     FILE *f = mustOpen(sampleFile, "w");
     writeMinimalVcfHeader(f, assembly->name);
     if (gpList == NULL)
 	{
 	warn("Unable to find any gene transcripts in '%s' (%s)",
 	     geneTdb->shortLabel, geneTdb->track);
 	writeArbitraryVariants(f, assembly);
 	}
     else
 	{
 	struct bed4 *bedList = NULL;
 	uint chromSize = annoAssemblySeqSize(assembly, gpList->chrom);
@@ -2196,37 +2196,38 @@
     }
 else if (sameString(variantTrack, hgvaUseVariantIds))
     {
     // Override search position if cart position doesn't include all variants:
     primary = makeVariantIdStreamer(assembly, maxVarRows, &chrom, &start, &end, &commentList);
     primaryLongLabel = hgvaVariantIdsLabel;
     }
 else
     {
     struct trackDb *varTdb = getVariantTrackDb(variantTrack);
     if (varTdb == NULL)
 	{
 	doUi();
 	return;
 	}
-    primary = hAnnoStreamerFromTrackDb(assembly, varTdb->table, varTdb, chrom, maxVarRows);
+    primary = hAnnoStreamerFromTrackDb(assembly, varTdb->table, varTdb, chrom, maxVarRows, NULL);
     primaryLongLabel = varTdb->longLabel;
     }
 
 enum annoGratorOverlap geneOverlapRule = agoMustOverlap;
 struct annoGrator *gpVarGrator = hAnnoGratorFromTrackDb(assembly, geneTdb->table, geneTdb, chrom,
-						   ANNO_NO_LIMIT, primary->asObj, geneOverlapRule);
+                                                        ANNO_NO_LIMIT, primary->asObj,
+                                                        geneOverlapRule, NULL);
 setGpVarFuncFilter(gpVarGrator);
 
 // Some grators may be used as both filters and output values. To avoid making
 // multiple grators for the same source, hash them by trackName:
 struct hash *gratorsByName = hashNew(8);
 
 struct annoGrator *snpGrator = NULL;
 char *snpDesc = NULL;
 if (cartUsualBoolean(cart, "hgva_rsId", FALSE))
     snpGrator = gratorForSnpBed4(gratorsByName, "", assembly, chrom, agoNoConstraint, &snpDesc);
 
 // Now construct gratorList in the order in which annoFormatVep wants to see them,
 // i.e. first the gpVar, then the snpNNN, then whatever else:
 struct annoGrator *gratorList = NULL;
 slAddHead(&gratorList, gpVarGrator);