7bc24686024ec14d351ab208b5179ab251d7c463
tdreszer
  Fri Oct 14 16:34:15 2011 -0700
Major work on bedFilt, psl and wigMaf to make them properly composite ready.
diff --git src/hg/hgTracks/wigMafTrack.c src/hg/hgTracks/wigMafTrack.c
index 890239d..583147d 100644
--- src/hg/hgTracks/wigMafTrack.c
+++ src/hg/hgTracks/wigMafTrack.c
@@ -153,66 +153,70 @@
 struct wigMafItem *newSpeciesItems(struct track *track, int height)
 /* Make up item list for all species configured in track settings */
 {
 struct dyString *order = dyStringNew(256);
 char option[MAX_SP_SIZE];
 char *species[MAX_SP_SIZE];
 char *groups[20];
 char *defaultOff[MAX_SP_SIZE];
 char sGroup[24];
 struct wigMafItem *mi = NULL, *miList = NULL;
 int group;
 int i;
 int speciesCt = 0, groupCt = 1;
 int speciesOffCt = 0;
 struct hash *speciesOffHash = newHash(0);
-char buffer[128];
+#define BRANEY_SAYS_USETARG_IS_OBSOLETE
+#ifndef BRANEY_SAYS_USETARG_IS_OBSOLETE
 char *speciesTarget = trackDbSetting(track->tdb, SPECIES_TARGET_VAR);
 char *speciesTree = trackDbSetting(track->tdb, SPECIES_TREE_VAR);
 bool useTarg;	/* use phyloTree to find shortest path */
 struct phyloTree *tree = NULL;
+#endif///ndef BRANEY_SAYS_USETARG_IS_OBSOLETE
 char *speciesUseFile = trackDbSetting(track->tdb, SPECIES_USE_FILE);
 char *msaTable = NULL;
 
 /* either speciesOrder or speciesGroup is specified in trackDb */
 char *speciesOrder = trackDbSetting(track->tdb, SPECIES_ORDER_VAR);
 char *speciesGroup = trackDbSetting(track->tdb, SPECIES_GROUP_VAR);
 char *speciesOff = trackDbSetting(track->tdb, SPECIES_DEFAULT_OFF_VAR);
 
 bool lowerFirstChar = TRUE;
 char *firstCase;
 
 firstCase = trackDbSetting(track->tdb, ITEM_FIRST_CHAR_CASE);
 if (firstCase != NULL)
     {
     if (sameWord(firstCase, "noChange")) lowerFirstChar = FALSE;
     }
 
-char *cfgPrefix = compositeViewControlNameFromTdb(track->tdb);
-safef(buffer, sizeof(buffer), "%s.vis",/*cfgPrefix*/track->track);
+#ifndef BRANEY_SAYS_USETARG_IS_OBSOLETE
+char buffer[128];
+safef(buffer, sizeof(buffer), "%s.vis",track->track); // According to Tim, this makes no sense as "vis"
 if (!cartVarExists(cart, buffer) && (speciesTarget != NULL))
     useTarg = TRUE;
 else
     {
     char *val;
 
     val = cartUsualString(cart, buffer, "useCheck");
     useTarg = sameString("useTarg",val);
     }
 
 if (useTarg && (tree = phyloParseString(speciesTree)) == NULL)
     useTarg = FALSE;
+#endif///ndef BRANEY_SAYS_USETARG_IS_OBSOLETE
 
 if (speciesOrder == NULL && speciesGroup == NULL && speciesUseFile == NULL)
     return getSpeciesFromMaf(track, height);
 
 if (speciesGroup)
     groupCt = chopLine(cloneString(speciesGroup), groups);
 
 if (speciesUseFile)
     {
     if ((speciesGroup != NULL) || (speciesOrder != NULL))
 	errAbort("Can't specify speciesUseFile and speciesGroup or speciesOrder");
     if (hIsGsidServer())
 	{
 	msaTable = trackDbSetting(track->tdb, "msaTable");
     	if (msaTable != NULL)
@@ -227,101 +231,110 @@
     else
 	{
     	speciesOrder = cartGetOrderFromFile(database, cart, speciesUseFile);
     	}
     speciesOff = NULL;
     }
 
 /* keep track of species configured off initially for track */
 if (speciesOff)
     {
     speciesOffCt = chopLine(cloneString(speciesOff), defaultOff);
     for (i = 0; i < speciesOffCt; i++)
         hashAdd(speciesOffHash, defaultOff[i], NULL);
     }
 
+char *prefix = track->track; // use when setting things to the cart
+if (tdbIsContainerChild(track->tdb))
+    prefix = tdbGetContainer(track->tdb)->track;
+
 /* Make up items for other organisms by scanning through group & species
    track settings */
 for (group = 0; group < groupCt; group++)
     {
     if (groupCt != 1 || !speciesOrder)
         {
         safef(sGroup, sizeof sGroup, "%s%s",
                                 SPECIES_GROUP_PREFIX, groups[group]);
         speciesOrder = trackDbRequiredSetting(track->tdb, sGroup);
         }
+#ifndef BRANEY_SAYS_USETARG_IS_OBSOLETE
     if (useTarg)
 	{
+        warn("BRANEY_SAYS useTarg should never be TRUE!");
 	char *ptr, *path;
 	struct hash *orgHash = newHash(0);
 	int numNodes, ii;
 	char *nodeNames[512];
 	char *species = NULL;
 	char *lowerString;
 
 	path = phyloNodeNames(tree);
 	numNodes = chopLine(path, nodeNames);
 	for(ii=0; ii < numNodes; ii++)
 	    {
 	    if ((ptr = hOrganism(nodeNames[ii])) != NULL)
 		{
 		ptr[0] = tolower(ptr[0]);
 		hashAdd(orgHash, ptr, nodeNames[ii]);
 		}
 	    else
 		{
 		hashAdd(orgHash, nodeNames[ii], nodeNames[ii]);
 		}
 	    }
 
 	lowerString = cartUsualString(cart, SPECIES_HTML_TARGET,speciesTarget);
 	lowerString[0] = tolower(lowerString[0]);
 	species = hashFindVal(orgHash, lowerString);
 	if ((ptr = phyloFindPath(tree, database, species)) != NULL)
 	    speciesOrder = ptr;
 	}
+#endif///ndef BRANEY_SAYS_USETARG_IS_OBSOLETE
 
-
-    safef(option, sizeof(option), "%s.speciesOrder", /*cfgPrefix*/track->track);
     speciesCt = chopLine(cloneString(speciesOrder), species);
-
     for (i = 0; i < speciesCt; i++)
         {
+#ifndef BRANEY_SAYS_USETARG_IS_OBSOLETE
 	if (!useTarg)
+#endif///ndef BRANEY_SAYS_USETARG_IS_OBSOLETE
 	    {
 	    /* skip this species if UI checkbox was unchecked */
-	    safef(option, sizeof(option), "%s.%s", cfgPrefix, species[i]);
-	    if (!cartVarExists(cart, option))
+            if (!cartVarExistsAnyLevel(cart, track->tdb,FALSE,species[i]))
+                {
 		if (hashLookup(speciesOffHash, species[i]))
+                    {
+                    safef(option, sizeof(option), "%s.%s", prefix, species[i]);
 		    cartSetBoolean(cart, option, FALSE);
-	    if (!cartUsualBoolean(cart, option, TRUE))
+                    }
+                }
+            if (!cartUsualBooleanClosestToHome(cart, track->tdb, FALSE, species[i],TRUE))
 		continue;
 	    }
         mi = newMafItem(species[i], group, lowerFirstChar);
         slAddHead(&miList, mi);
         }
     }
 
 slReverse(&miList);
 for (mi = miList; mi != NULL; mi = mi->next)
     {
     mi->height = height;
     dyStringPrintf(order, "%s ",mi->db);
     }
-safef(option, sizeof(option), "%s.speciesOrder", /*cfgPrefix*/track->track);
+safef(option, sizeof(option), "%s.speciesOrder", prefix);
 cartSetString(cart, option, order->string);
-compositeViewControlNameFree(&cfgPrefix);
 slReverse(&miList);
 
 return miList;
 }
 
 static struct wigMafItem *scoreItem(int scoreHeight, char *label)
 /* Make up item that will show the score */
 {
 struct wigMafItem *mi;
 
 AllocVar(mi);
 mi->name = cloneString(label);
 mi->height = scoreHeight;
 return mi;
 }
@@ -1063,45 +1076,46 @@
 struct sqlResult *sr = NULL;
 char **row = NULL;
 int rowOffset = 0;
 struct mafSummary *ms, *summaryList;
 struct hash *componentHash = newHash(6);
 struct hashEl *hel;
 struct hashCookie cookie;
 struct dyString *where = dyStringNew(256);
 char *whereClause = NULL;
 boolean useIrowChains = TRUE;
 char option[64];
 
 if (miList == NULL)
     return FALSE;
 
+char *prefix = track->track; // use when setting things to the cart
+if (tdbIsContainerChild(track->tdb))
+    prefix = tdbGetContainer(track->tdb)->track;
+
 /* get summary table name from trackDb */
 if ((summary = summarySetting(track)) == NULL)
     return FALSE;
 
-char *cfgPrefix = compositeViewControlNameFromTdb(track->tdb);
-
-safef(option, sizeof(option), "%s.%s", cfgPrefix, MAF_CHAIN_VAR);
-compositeViewControlNameFree(&cfgPrefix);
-if (cartVarExists(cart, option))
-    useIrowChains = cartCgiUsualBoolean(cart, option, TRUE);
+if (cartVarExistsAnyLevel(cart, track->tdb,FALSE,MAF_CHAIN_VAR))
+    useIrowChains = cartUsualBooleanClosestToHome(cart, track->tdb, FALSE, MAF_CHAIN_VAR,TRUE);
 else
     {
     char *irowString = trackDbSetting(track->tdb, "irows");
     if (irowString && sameString(irowString, "off"))
 	useIrowChains = FALSE;
+    safef(option, sizeof(option), "%s.%s", prefix, MAF_CHAIN_VAR);
     cartSetBoolean(cart, option, useIrowChains);
     }
 
 /* Create SQL where clause that will load up just the
  * summaries for the species that we are including. */
 conn = hAllocConn(database);
 dyStringAppend(where, "src in (");
 for (mi = miList; mi != NULL; mi = mi->next)
     {
     if (!isPairwiseItem(mi))
 	/* exclude non-species items (e.g. conservation wiggle */
 	continue;
     dyStringPrintf(where, "'%s'", mi->db);
     if (mi->next != NULL)
 	dyStringAppend(where, ",");
@@ -1287,45 +1301,46 @@
 static boolean drawPairsFromMultipleMaf(struct track *track,
         int seqStart, int seqEnd,
         struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font,
         Color color, enum trackVisibility vis)
 /* Draw pairwise display from maf of multiple alignment.
  * Extract pairwise alignments from maf and rescore.
  * This is used only when zoomed-in.
  */
 {
 struct wigMafItem *miList = track->items, *mi = miList;
 int graphHeight = 0;
 Color pairColor = (vis == tvFull ? track->ixAltColor : color);
 boolean useIrowChains = TRUE;
 char option[64];
 
+char *prefix = track->track; // use when setting things to the cart
+if (tdbIsContainerChild(track->tdb))
+    prefix = track->tdb->parent->track;
+
 struct mafPriv *mp = getMafPriv(track);
 if (miList == NULL || mp->list == NULL)
     return FALSE;
 
-char *cfgPrefix = compositeViewControlNameFromTdb(track->tdb);
-
-safef(option, sizeof(option), "%s.%s", cfgPrefix, MAF_CHAIN_VAR);
-compositeViewControlNameFree(&cfgPrefix);
-if (cartVarExists(cart, option))
-    useIrowChains = cartCgiUsualBoolean(cart, option, TRUE);
+if (cartVarExistsAnyLevel(cart, track->tdb,FALSE,MAF_CHAIN_VAR))
+    useIrowChains = cartUsualBooleanClosestToHome(cart, track->tdb, FALSE, MAF_CHAIN_VAR,TRUE);
 else
     {
     char *irowString = trackDbSetting(track->tdb, "irows");
     if (irowString && sameString(irowString, "off"))
 	useIrowChains = FALSE;
+    safef(option, sizeof(option), "%s.%s", prefix, MAF_CHAIN_VAR);
     cartSetBoolean(cart, option, useIrowChains);
     }
 
 if (vis == tvFull)
     graphHeight = pairwiseWigHeight(track);
 
 /* display pairwise items */
 for (mi = miList; mi != NULL; mi = mi->next)
     {
     struct mafAli *mafList = NULL, *maf, *pairMaf;
     struct mafComp *mcThis, *mcPair = NULL, *mcMaster = NULL;
 
     if (mi->ix < 0)
         /* ignore item for the score */
         continue;
@@ -1750,54 +1765,57 @@
         MgFont *font, Color color, enum trackVisibility vis,
 	struct wigMafItem *miList)
 /* Draw base-by-base view, return new Y offset. */
 {
 struct wigMafItem *mi;
 struct mafAli *mafList, *maf, *sub;
 struct mafComp *mc, *mcMaster;
 int lineCount = slCount(miList);
 char **lines = NULL, *selfLine, *insertLine;
 int *insertCounts;
 int i, x = xOff, y = yOff;
 struct dnaSeq *seq = NULL;
 struct hash *miHash = newHash(9);
 struct hash *srcHash = newHash(0);
 char dbChrom[64];
-char buf[1024];
 char option[64];
 int alignLineLength = winBaseCount * 2;
         /* doubled to allow space for insert counts */
 boolean complementBases = cartUsualBooleanDb(cart, database, COMPLEMENT_BASES_VAR, FALSE);
 bool dots = FALSE;         /* configuration option */
 /* this line must be longer than the longest base-level display */
 char noAlignment[2000];
 boolean useIrowChains = TRUE;
 int offset;
 char *framesTable = NULL;
 char *defaultCodonSpecies = cartUsualString(cart, SPECIES_CODON_DEFAULT, NULL);
 char *codonTransMode = NULL;
 boolean startSub2 = FALSE;
 
 int mafOrig = 0;
 int mafOrigOffset = 0;
 char query[256];
 struct mafPriv *mp = getMafPriv(track);
 char *mafFile = NULL;
 struct sqlConnection *conn2 = NULL;
 struct sqlConnection *conn3 = NULL;
 char *tableName = NULL;
 
+char *prefix = track->track; // use when setting things to the cart
+if (tdbIsContainerChild(track->tdb))
+    prefix = tdbGetContainer(track->tdb)->track;
+
 if (mp->ct != NULL)
     {
     conn2 = hAllocConn(CUSTOM_TRASH);
     conn3 = hAllocConn(CUSTOM_TRASH);
     tableName = mp->ct->dbTableName;
     mafFile = getCustomMafFile(track);
     }
 else
     {
     conn2 = hAllocConn(database);
     conn3 = hAllocConn(database);
     tableName = track->table;
     mafFile = getTrackMafFile(track);  // optional
     }
 
@@ -1817,79 +1835,73 @@
 if (defaultCodonSpecies == NULL)
     defaultCodonSpecies = trackDbSetting(track->tdb, "speciesCodonDefault");
 
 if (defaultCodonSpecies == NULL)
     defaultCodonSpecies = database;
 
 if (seqStart > 2)
     {
     startSub2 = TRUE;
     seqStart -=2;
     }
 seqEnd +=2;
 if (seqEnd > seqBaseCount)
     seqEnd = seqBaseCount;
 
-char *cfgPrefix = compositeViewControlNameFromTdb(track->tdb);
-
-safef(option, sizeof(option), "%s.%s", cfgPrefix, MAF_DOT_VAR);
-if (cartVarExists(cart, option))
-    {
-    dots = cartCgiUsualBoolean(cart, option, FALSE);
-    }
+if (cartVarExistsAnyLevel(cart, track->tdb,FALSE,MAF_DOT_VAR))
+    dots = cartUsualBooleanClosestToHome(cart, track->tdb, FALSE, MAF_DOT_VAR,TRUE);
 else
     {
     char *dotString = trackDbSetting(track->tdb, MAF_DOT_VAR);
     if (dotString && sameString(dotString, "on"))
 	{
 	dots = TRUE;
+        safef(option, sizeof(option), "%s.%s", prefix, MAF_DOT_VAR);
 	cartSetBoolean(cart, option, TRUE);
 	}
     }
 
-safef(buf, sizeof(buf), "%s.frames",/*cfgPrefix*/track->track);
-if (cartVarExists(cart, buf))
-    framesTable = cartUsualString(cart, buf, NULL);
+if (cartVarExistsAnyLevel(cart, track->tdb,FALSE,"frames"))
+    framesTable = cartOptionalStringClosestToHome(cart, track->tdb,FALSE,"frames");
 else
     framesTable = trackDbSetting(track->tdb, "frames");
 
 if (framesTable)
     {
-    safef(buf, sizeof(buf), "%s.codons",cfgPrefix);
-    codonTransMode = cartUsualString(cart, buf, "codonDefault");
+    codonTransMode = cartUsualStringClosestToHome(cart, track->tdb,FALSE,"codons", "codonDefault");
     if (sameString("codonNone", codonTransMode))
 	framesTable = NULL;
     }
 
 boolean newTableType = FALSE;
 
 if (framesTable != NULL)
     newTableType = hHasField(database, framesTable, "isExonStart");
 
 /* initialize "no alignment" string to o's */
 for (i = 0; i < sizeof noAlignment - 1; i++)
     noAlignment[i] = UNALIGNED_SEQ;
 
 
-safef(option, sizeof(option), "%s.%s", cfgPrefix, MAF_CHAIN_VAR);
-if (cartVarExists(cart, option))
-    useIrowChains = cartCgiUsualBoolean(cart, option, TRUE);
+if (cartVarExistsAnyLevel(cart, track->tdb,FALSE,MAF_CHAIN_VAR))
+    useIrowChains = cartUsualBooleanClosestToHome(cart, track->tdb, FALSE, MAF_CHAIN_VAR,TRUE);
 else
     {
     char *irowString = trackDbSetting(track->tdb, "irows");
     if (irowString && sameString(irowString, "off"))
 	useIrowChains = FALSE;
+    safef(option, sizeof(option), "%s.%s", prefix, MAF_CHAIN_VAR);
     cartSetBoolean(cart, option, useIrowChains);
     }
 
 /* Allocate a line of characters for each item. */
 AllocArray(lines, lineCount);
 lines[0] = needMem(alignLineLength);
 for (i=1; i<lineCount; ++i)
     {
     lines[i] = needMem(alignLineLength);
     memset(lines[i], ' ', alignLineLength - 1);
     }
 
 /* Give nice names to first two. */
 insertLine = lines[0];
 selfLine = lines[1];
@@ -2160,44 +2172,41 @@
 	if (label->stringSize > haveRoomFor)
 	    {
 	    dyStringClear(label);
 	    dyStringPrintf(label, "%c",(insertCounts[offset] % 3) == 0 ? '*' : '+');
 	    }
 	hvGfxTextCentered(hvg, x1+x - (width/winBaseCount)/2, y, x2-x1, mi->height,
 		getOrangeColor(), font, label->string);
 	dyStringFree(&label);
 	}
     }
 y += mi->height;
 
 /* draw alternating colors behind base-level alignments */
     {
     int alternateColorBaseCount, alternateColorBaseOffset;
-    safef(buf, sizeof(buf), "%s.%s", cfgPrefix, BASE_COLORS_VAR);
-    alternateColorBaseCount = cartCgiUsualInt(cart, buf, 0);
-    safef(buf, sizeof(buf), "%s.%s", cfgPrefix, BASE_COLORS_OFFSET_VAR);
-    alternateColorBaseOffset = cartCgiUsualInt(cart, buf, 0);
+    alternateColorBaseCount = cartUsualIntClosestToHome(cart, track->tdb, FALSE, BASE_COLORS_VAR, 0);
+    alternateColorBaseOffset = cartUsualIntClosestToHome(cart, track->tdb, FALSE, BASE_COLORS_OFFSET_VAR, 0);
     if (alternateColorBaseCount != 0)
         {
         int baseWidth = spreadStringCharWidth(width, winBaseCount);
         int colorX = x + alternateColorBaseOffset * baseWidth;
         alternateBlocksBehindChars(hvg, colorX, y-1, width,
                 mi->height*(lineCount-1), tl.mWidth, winBaseCount,
                 alternateColorBaseCount, shadesOfSea[0], MG_WHITE);
         }
     }
-compositeViewControlNameFree(&cfgPrefix);
 
 /* draw base-level alignments */
 for (mi = miList->next, i=1; mi != NULL && mi->db != NULL; mi = mi->next, i++)
     {
     char *line;
 
     line  = lines[i];
     /* TODO: leave lower case in to indicate masking ?
        * NOTE: want to make sure that all sequences are soft-masked
        * if we do this */
     /* HAVE DONE:  David doesn't like lower case by default
      * TODO: casing based on quality values ?? */
     alignSeqToUpperN(line);
     if (complementBases)
         {
@@ -2476,32 +2485,33 @@
 track->mapsSelf = TRUE;
 //track->canPack = TRUE;
 
 /* deal with conservation wiggle(s) */
 consWigList = wigMafWiggles(database, tdb);
 if (consWigList == NULL)
     return;
 
 /* determine which conservation wiggles to use -- from cart,
  or if none there, use first entry in trackDb setting */
 boolean first = TRUE;
 for (consWig = consWigList; consWig != NULL; consWig = consWig->next)
     {
     if (differentString(consWig->leftLabel, DEFAULT_CONS_LABEL))
         {
-        char *wigVar = wigMafWiggleVar(tdb, consWig);
-        if (!cartCgiUsualBoolean(cart, wigVar, first))
+        char *wigVar = wigMafWiggleVar(tdb->track, consWig);
+        char *wigVarSuffix = wigVar + strlen (tdb->track) + 1;
+        if (!cartUsualBooleanClosestToHome(cart, tdb, FALSE, wigVarSuffix, first))
             continue;
         }
     first = FALSE;
 
     //  Manufacture and initialize wiggle subtrack, both tdb and track
     struct trackDb *wigTdb = CloneVar(tdb);
     wigType = newDyString(64);
     dyStringPrintf(wigType, "type wig ");
     for (i = 1; i < wordCount; i++)
         dyStringPrintf(wigType, "%s ", words[i]);
     wigTdb->type = cloneString(wigType->string);
     wigTdb->track = consWig->table;
     wigTdb->table= consWig->table;
 
     /* Tweak wiggle left labels: replace underscore with space and