ebb119f63d024ea706a6922adf67bb9956d5f049
kate
  Tue Sep 3 16:33:52 2019 -0700
More fixes for multi-region (cross-chrom and non-cluster mode). refs #22422

diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index 45c4a7f..2d9d289 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -465,50 +465,54 @@
 struct window *w;
 struct track *tgSave = tg;
 
 // find out which items are the same,
 // and belong on the same line with (probably one) label:
 struct hash *sameItem = newHash(10);
 // TODO estimate this as log base 2 # items in all windows
 //struct hash *itemDone = newHash(10);  // TODO I do not need this yet in this version if no dupes.
 for(w=windows,tg=tgSave; w; w=w->next,tg=tg->nextWindow)
     {
     // Have to init these here
     // save old spaceSaver until callback on another window later
     struct spaceSaver *ssOld = tg->ss;
     tg->ss = spaceSaverNew(0, fullInsideWidth, maxCount);  // actual params do not matter, just using ss->nodeList.
     tg->ss->next = ssOld;
+    boolean useItemNameAsKey = isTypeUseItemNameAsKey(tg);
+    boolean useMapItemNameAsKey = isTypeUseMapItemNameAsKey(tg);
     char *chrom = w->chromName;
     for (item = tg->items; item != NULL; item = item->next)
 	{
 	int baseStart = tg->itemStart(tg, item);
 	int baseEnd = tg->itemEnd(tg, item);
 	if (baseStart < w->winEnd && baseEnd > w->winStart)
 	    { // it intersects the window
 	    char *mapItemName = tg->mapItemName(tg, item);
 	    char key[1024];
 	    // TODO I am making the key based on chrom, so no items will be aligned on the same line
 	    // that are in different chromosomes.  If the itemName is unique per chromosome or in other ways
 	    // then itemName alone could be the key.
 	    // TODO we know that for some tracks there is great duplication, names are not unique,
 	    // even this key of position+name will not be unique enough.
 	    // But fixing that may require creating a new function that converts the item into a string
 	    // and then use that to prove uniqueness, or as near as can be had.
 	    //
 	    // For now, this should be good enough to illustrate the basic behavior we want to see.
-	    if (isTypeUseItemNameAsKey(tg))
+	    if (useItemNameAsKey)
 		safef(key, sizeof key, "%s",  tg->itemName(tg, item));
+	    else if (useMapItemNameAsKey)
+		safef(key, sizeof key, "%s", mapItemName);
             else
 		safef(key, sizeof key, "%s:%d-%d %s", chrom, baseStart, baseEnd, mapItemName);
 	    struct hashEl *hel = hashLookup(sameItem, key);
 	    struct sameItemNode *sin;
 	    if (hel)
 		{
 		sin = (struct sameItemNode *)hel->val;
 		if (sin->window == w)
 		    {
 		    // dupe found for key, all windows should have the same number of dupes
 		    //char *itemName = tg->itemName(tg, item);
 		    //char *itemDataName = getItemDataName(tg, itemName);
 		    //char *mapItemName = tg->mapItemName(tg, item);
 		    //warn("duplicate keys in same window.\n key=[%s] itemDataName=%s mapItemName=%s w=%lu sin->window=%lu",  // TODO
 			//key, itemDataName, mapItemName, (unsigned long) w, (unsigned long) sin->window);
@@ -528,45 +532,48 @@
 	}
     }
 
 // do spaceSaver layout
 struct spaceSaver *ss;
 ss = spaceSaverNew(0, fullInsideWidth, maxCount);
 ss->vis = vis;
 for(w=windows,tg=tgSave; w; w=w->next,tg=tg->nextWindow)
     {
     // save these values so we can detect vis and window changes
     tg->ss->vis = vis;
     tg->ss->window = w;
     char *chrom = w->chromName;
     // int winOffset = w->insideX - fullInsideX;  // no longer needed
     double scale = (double)w->insideWidth/(w->winEnd - w->winStart);
-    boolean useTypeItemNameAsKey = isTypeUseItemNameAsKey(tg);
+    boolean useItemNameAsKey = isTypeUseItemNameAsKey(tg);
+    boolean useMapItemNameAsKey = isTypeUseMapItemNameAsKey(tg);
     for (item = tg->items; item != NULL; item = item->next)
 	{
 	// TODO match items from different windows by using item start end and name in hash?
 	int baseStart = tg->itemStart(tg, item);
 	int baseEnd = tg->itemEnd(tg, item);
 	if (baseStart < w->winEnd && baseEnd > w->winStart)
 	    { // it intersects the window
 
 	    char *mapItemName = tg->mapItemName(tg, item);
 	    char key[1024];
 	    // TODO see key caveats above
 	    // For now, this should be good enough to illustrate the basic behavior we want to see.
-	    if (useTypeItemNameAsKey)
+	    if (useItemNameAsKey)
 		safef(key, sizeof key, "%s",  tg->itemName(tg, item));
+	    else if (useMapItemNameAsKey)
+		safef(key, sizeof key, "%s",  mapItemName);
 	    else
 		safef(key, sizeof key, "%s:%d-%d %s", chrom, baseStart, baseEnd, mapItemName);
 	    struct hashEl *hel = hashLookup(sameItem, key);
 	    if (!hel)
 		{
 		if (tg->networkErrMsg) // probably timed-out before thread finished adding more items.
 		    break;
 		errAbort("unexpected error: lookup of key [%s] in sameItem hash failed.", key);
 		}
 	    struct sameItemNode *sin = (struct sameItemNode *)hel->val;
 	    if (!sin)
 		errAbort("sin empty (hel->val)!");
 	    if (!sin->done)
 		{ // still needs to be done
 		slReverse(&hel->val);