ba31086d08e0c051ad23953fc9bb462e9135cb58
galt
  Wed Feb 24 13:06:05 2016 -0800
Removing DEBUG warnings from hgTracks multi-region code.

diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index 0b0cc8a..f8d6005 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -407,38 +407,34 @@
 slReverse(&newSs);
 tg->ss = newSs;
 return result;
 }
 
 
 int packCountRowsOverflow(struct track *tg, int maxCount,
                           boolean withLabels, boolean allowOverflow, enum trackVisibility vis)
 /* Return packed height. */
 {
 
 // allowOverflow is currently ONLY used by xenoMrna and est tracks.
 //  When true,  the extra rows are kept, printed at the bottom in dense and Last Row: overlow count appears at bottom of leftLabel area.
 //  When false, the extra rows are tossed, the count seems to equal overflow limit + 2, and limitVisibility lowers vis and retries.
 
-//warn("packCountRowsOverflow tg->track %s (%sfirst window) tg->visibility=%d tg->limitedVis=%d tg->limitedVisSet=%d vis=%d insideWidth=%d", 
-//tg->track, currentWindow == windows ? "" : "non-", tg->visibility, tg->limitedVis, tg->limitedVisSet, vis, insideWidth); // DEBUG REMOVE
-
 // do not calculate if still loading all windows
 if (trackLoadingInProgress) // we pack after all windows are loaded.
     {
     // do not set ss yet
-    //warn("trackLoadingInProgress, exiting currentWindow=%lu windows=%lu", (unsigned long) currentWindow, (unsigned long) windows); // DEBUG REMOVE
     return 0;  // height of 0 triggers unsetting limitedVis since our data is not all loaded yet and it will get set later.
     }
 
 // do not re-calculate if not needed
 if (tg->ss)
     {
     if (tg->ss->window != currentWindow)
 	errAbort("unexpected current window %lu, expected %lu", (unsigned long) currentWindow, (unsigned long) tg->ss->window);
     struct spaceSaver *ss = findSpaceSaverAndFreeOldOnes(tg, vis);
     if (ss)
 	return ss->rowCount;
     // Falls thru here if a new visibility is needed, such as full changing to pack after limitVisibility.
     // This will usually be when it is the first window and it is requesting a new vis.
     }
 
@@ -489,31 +485,31 @@
 	    if (isTypeUseItemNameAsKey(tg))
 		safef(key, sizeof key, "%s",  tg->itemName(tg, item));
 	    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",  // DEBUG REMOVE
+		    //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);
 		    }
 		}
 	    else
 		{
 		hashAdd(sameItem, key, NULL);
 		hel = hashLookup(sameItem, key);
 		}
 	    AllocVar(sin);
 	    sin->window = w;
 	    sin->item = item;
 	    sin->ss = tg->ss;
 	    slAddHead(&hel->val, sin);
 	    }
 	}
@@ -535,44 +531,42 @@
 	{
 	// 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 (isTypeUseItemNameAsKey(tg))
 		safef(key, sizeof key, "%s",  tg->itemName(tg, item));
 	    else
 		safef(key, sizeof key, "%s:%d-%d %s", chrom, baseStart, baseEnd, mapItemName);
-	    //warn("spaceSaver key=[%s] window=%lu", key, (unsigned long)w); // DEBUG REMOVE
 	    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
-		//warn("Reversed list."); // DEBUG REMOVE
 		slReverse(&hel->val);
 		sin = (struct sameItemNode *)hel->val;
 		}
 
 	    bool noLabel = FALSE;
 	    struct window *firstWin = sin->window;  // first window
 	    struct window *lastWin = NULL;
 	    bool foundWork = FALSE;
 
 	    struct spaceRange *rangeList=NULL, *range;
 	    struct spaceNode *nodeList=NULL, *node;
             int rangeWidth = 0; // width in pixels of all ranges
 	    for(; sin; sin=sin->next)
 		{
 
@@ -659,31 +653,30 @@
 	}
     spaceSaverFinish(tg->ss);
     }
 // must assign at end to get final row count
 for(tg=tgSave; tg; tg=tg->nextWindow)
     {
     tg->ss->rowCount   = ss->rowCount;
     }
 tg = tgSave;
 spaceSaverFree(&ss);
 
 ss = findSpaceSaverAndFreeOldOnes(tg, vis);
 if (!ss)
     errAbort("unexpected error findSpaceSaverAndFreeOldOnes returned NULL at end of pack function");
 
-//warn("packCountRowsOverflow returning rowCount=%d vis=%d tg->track=%s tg->ss->window=%lu", tg->ss->rowCount, tg->ss->vis, tg->track, (unsigned long) tg->ss->window);
 return ss->rowCount;
 }
 
 int packCountRows(struct track *tg, int maxCount, boolean withLabels, enum trackVisibility vis)
 /* Return packed height. */
 {
 return packCountRowsOverflow(tg, maxCount, withLabels, FALSE, vis);
 }
 
 char *getItemDataName(struct track *tg, char *itemName)
 /* Translate an itemName to its itemDataName, using tg->itemDataName if is not
  * NULL. The resulting value should *not* be freed, and it should be assumed
  * that it will only remain valid until the next call of this function.*/
 {
 return (tg->itemDataName != NULL) ? tg->itemDataName(tg, itemName)
@@ -721,33 +714,30 @@
 {
 int answer = maxItemsToUseOverflowDefault;
 char *maxItemsString = trackDbSetting(tg->tdb, "maxItemsToOverflow");
 if (maxItemsString != NULL)
     answer = sqlUnsigned(maxItemsString);
 
 return answer;
 }
 
 int tgFixedTotalHeightOptionalOverflow(struct track *tg, enum trackVisibility vis,
                                        int lineHeight, int heightPer, boolean allowOverflow)
 /* Most fixed height track groups will use this to figure out the height
  * they use. */
 {
 
-//warn("calling tgFixedTotalHeightOptionalOverflow tg->track=%s. Passed in vis=%d lineHeight=%d, heightPer=%d, allowOverflow=%d", 
-	//tg->track, vis, lineHeight, heightPer, allowOverflow); // DEBUG REMOVE
-
 boolean doWiggle = cartOrTdbBoolean(cart, tg->tdb, "doWiggle" , FALSE);
 if (doWiggle)
     {
     struct wigCartOptions *wigCart = tg->wigCartData;
     if (tg->wigCartData == NULL)
 	{
 	wigCart = wigCartOptionsNew(cart, tg->tdb, 0, NULL );
 	tg->wigCartData = (void *) wigCart;
 	}
     return wigTotalHeight(tg, vis);
     }
 
 int rows;
 double maxHeight = maximumTrackHeight(tg);
 int itemCount = slCount(tg->items);
@@ -793,32 +783,30 @@
 	tg->heightPer = heightPer/2;
 	if ((tg->heightPer & 1) == 0)
 	    tg->heightPer -= 1;
 	tg->lineHeight = tg->heightPer + 1;
 	if(allowOverflow && itemCount < maxItemsToUseOverflow)
 	    rows = packCountRowsOverflow(tg, floor(maxHeight/tg->lineHeight), FALSE, allowOverflow, vis);
 	else
 	    rows = packCountRowsOverflow(tg, floor(maxHeight/tg->lineHeight)+1, FALSE, FALSE, vis);
 	break;
 	}
     case tvDense:
     default:
         rows = 1;
 	break;
     }
-//warn("called tgFixedTotalHeightOptionalOverflow tg->track=%s. tg->lineHeight=%d, tg->heightPer=%d, itemCount=%d, rows=%d", 
-	//tg->track, tg->lineHeight, tg->heightPer, itemCount, rows); // DEBUG REMOVE
 tg->height = rows * tg->lineHeight;
 return tg->height;
 }
 
 
 int tgFixedTotalHeightNoOverflow(struct track *tg, enum trackVisibility vis)
 /* Most fixed height track groups will use this to figure out the height
  * they use. */
 {
 return tgFixedTotalHeightOptionalOverflow(tg,vis, tl.fontHeight+1, tl.fontHeight, FALSE);
 }
 
 int tgFixedTotalHeightUsingOverflow(struct track *tg, enum trackVisibility vis)
 /* Returns how much height this track will use, tries to pack overflow into
   last row to avoid being more than maximumTrackHeight(). */
@@ -910,43 +898,40 @@
             vis = tvDense;
         dyStringPrintf(dy, "&%s=%s", encodedMapName, hStringFromTv(vis));
         freeMem(encodedMapName);
         }
     }
 return dy;
 }
 
 boolean isWithCenterLabels(struct track *track)
 /* Cases: only TRUE when global withCenterLabels is TRUE
  * If track->tdb has a centerLabelDense setting, go with it.
 // * If composite child then no center labels in dense mode. */
 {
 if (!withCenterLabels)
     {
-    //warn("isWithCenterLabels returns FALSE because withCenterLabels is FALSE track %s", track->track); // DEBUG REMOVE
     return FALSE;
     }
 if (track != NULL)
     {
     char *centerLabelsDense = trackDbSetting(track->tdb, "centerLabelsDense");
     if (centerLabelsDense)
         {
-	//warn("isWithCenterLabels returns sameWord(centerLabelsDense, \"on\")=%d track %s", sameWord(centerLabelsDense, "on"), track->track); // DEBUG REMOVE
         return sameWord(centerLabelsDense, "on");
         }
     }
-//warn("isWithCenterLabels returns withCenterLabels=%d track %s", withCenterLabels, track->track); // DEBUG REMOVE
 return withCenterLabels;
 }
 
 boolean isCenterLabelConditionallySeen(struct track *track)
 // returns FALSE if track and prevTrack have same parent, and are both dense subtracks
 {
 if (isCenterLabelConditional(track))
     {
     if (track->prevTrack
     &&  track->parent == track->prevTrack->parent
     &&  isCenterLabelConditional(track->prevTrack))
         return FALSE;
     }
 return isWithCenterLabels(track);
 }
@@ -982,31 +967,30 @@
     {
     dyStringAppend(ui, "&");
     dyStringAppend(ui, extra);
     }
 if (chrom == NULL)
     {
     chrom = virtChromName;
     start = virtWinStart;
     end = virtWinEnd;
     }
 char pos[512];
 safef(pos,sizeof(pos),"%s:%ld-%ld", chrom, start+1, end);
 if (virtualSingleChrom())
     {
     char *newPos = disguisePositionVirtSingleChrom(pos); // DISGUISE POS
-    //warn("mapBoxReinvoke: pos=%s newPos=%s", pos, newPos);  // DEBUG REMOVE
     safef(pos,sizeof(pos),"%s", newPos);
     freeMem(newPos);
     }
 
 if (theImgBox && curImgTrack)
     {
     char link[512];
     safef(link,sizeof(link),"%s?position=%s&%s",       // NOTE: position may need removing
           hgTracksName(), pos, ui->string);    //       due to portal
     if (!revCmplDisp && x < fullInsideX)  // Do not toggle on side label!
         {
         width -= (fullInsideX+1 - x);
         if (width <= 1)
             {
             freeDyString(&ui);
@@ -2077,56 +2061,55 @@
 return sfA->start - sfB->start;
 }
 
 int exonSlRefReverseCmp(const void *va, const void *vb)
 /* Reverse of the exonSlRefCmp sort. */
 {
 return -1 * exonSlRefCmp(va, vb);
 }
 
 
 void linkedFeaturesNextPrevExonFind(struct track *tg, boolean next, struct convertRange *crList)
 //char *newChrom, int newWinStart, int newWinEnd, long *retVirtWinStart, long *retVirtWinEnd
 /* Find next-exon function for linkedFeatures.  Finds corresponding position on virtual chrom for new winStart/winEnd of exon non-virt position,
  * and returns it. This function was cloned from linkedFeaturesLabelNextPrevItem and modified. */
 {
-//warn("got here linkedFeaturesNextPrevExon next=%d", next); // DEBUG REMOVE
-
-// TODO we could exit this routine faster for the case where it would not be found
-//  if we know that the virt chrom is made out of ascending non-overlapping chrom regions.
 
 struct convertRange *cr;
 
 // Special case speed optimization. (It still works without this).
 if (!virtMode)
     { 
     for (cr=crList; cr; cr=cr->next)
 	{
 	if (cr->skipIt)
 	    {
 	    cr->vStart = -1;
 	    cr->vEnd   = -1;
 	    }
 	else
 	    {
 	    cr->vStart = cr->start;
 	    cr->vEnd   = cr->end;
 	    }
 	}
     return;
     }
 
+// TODO we could exit this routine faster for the case where it would not be found
+//  if we know that the virt chrom is made out of ascending non-overlapping chrom regions.
+
 // set found for skipIts
 for (cr=crList; cr; cr=cr->next)
     {
     if (cr->skipIt)
 	{
 	cr->found = TRUE;
 	}
     }
 
 long start = virtWinStart;
 long end = virtWinEnd;
 long size = virtWinBaseCount;
 long sizeWanted = size;
 long totalFetched = 0;
 boolean firstTime = TRUE;
@@ -2161,93 +2144,86 @@
 	// include the original window so we can detect overlap with it.
 	long xStart = start, xEnd = end;
 	if (firstTime)
 	    {
 	    firstTime = FALSE;
 	    if (next)
 		{
 		xStart = virtWinStart;
 		}
 	    else
 		{
 		xEnd = virtWinEnd;
 		}
 	    }
 
-	//warn("Expanding search window to start=%ld end=%ld size=%ld sizeWanted=%ld", xStart, xEnd, size, sizeWanted); // DEBUG REMOVE
+	// Expanding search window to xStart, xEnd, size, sizeWanted
 
 	struct window *windows = makeWindowListFromVirtChrom(xStart, xEnd);
 
 	totalFetched += (xEnd - xStart);
 
-	//warn("#WINDOWS READ=%d grand totalFetched=%ld", slCount(windows), totalFetched); // DEBUG REMOVE
-
 	struct window *w;
 	for(w=windows; w; w=w->next)
 	    {
 	    for (cr=crList; cr; cr=cr->next)
 		{
 
 		if (cr->skipIt)
 		    continue;
 
 		// exon and region overlap?
 		if (sameString(w->chromName, cr->chrom) && (cr->end > w->winStart) && (w->winEnd > cr->start)) // overlap
 		    { // clip exon to region
 
-		    //warn("region overlap: w->chromName=%s, w->winStart=%d w->winEnd=%d",w->chromName,w->winStart,w->winEnd); // DEBUG REMOVE
-
+		    //region overlaps?
 		    int s = max(w->winStart, cr->start); 
 		    int e = min(w->winEnd, cr->end);
 		    long vs = w->virtStart + (s - w->winStart);
 		    long ve = w->virtEnd - (w->winEnd - e);
 
-		    //warn("exon and region overlap: s=%d e=%d vs=%ld ve=%ld overlap=e-s=%d", s, e, vs, ve, e-s); // DEBUG REMOVE
-
+		    // exon and region overlap
 		    if (cr->found)
 			{ // if existing, extend its range
 			cr->vStart = min(vs, cr->vStart);
 			cr->vEnd = max(ve, cr->vEnd);
-			//warn("updating vr, new values vStart=%ld vEnd=%ld", cr->vStart, cr->vEnd); // DEBUG REMOVE
 			}
 		    else
 			{ // first find
-			//warn("creating new vr vs=%ld ve=%ld", vs, ve); // DEBUG REMOVE
 			cr->found = TRUE;
 			cr->vStart = vs;
 			cr->vEnd = ve;
 			}
 		    
 		    }
 		}
 	    }
 
 	slFreeList(&windows);
 
 	boolean vrFound = TRUE;
 	for (cr=crList; cr; cr=cr->next)
 	    {
 	    if (!cr->found)
 		vrFound = FALSE;
 	    }	    
 	if (vrFound)
 	    break;
 
 	// give up if we read this amount without finding anything
 	if (totalFetched > (virtWinBaseCount+1000000)) //  max gene size supported 1MB supports most genes.
 	    {
-	    //warn("totalFetched=%ld > 1000000, breaking out of loop.", totalFetched); // DEBUG REMOVE
 	    break;
 	    }
 	
 
 try_again:    
 	sizeWanted *= 2;
 	if (next)
 	    {
 	    start = end;
 	    end += sizeWanted;
 	    if (end > virtSeqBaseCount)
 		end = virtSeqBaseCount;
 	    }
 	else
 	    {
@@ -2266,42 +2242,40 @@
 	    break;
 	    }
 
 	}
 
 /* Finally, we got something. */
 int saveSizeWanted = sizeWanted;
 sizeWanted = virtWinEnd - virtWinStart;  // resetting sizeWanted back to the original windows span size
 
 for (cr=crList; cr; cr=cr->next)
     {
     if (cr->found && !cr->skipIt)
 	{
 	if (next)
 	    {
-	    //warn("nearest found vStart=%ld vEnd=%ld", cr->vStart, cr->vEnd); // DEBUG REMOVE
-	    // are we dangling off the end, need to expand search to find full span
+	    // if dangling off the end, need to expand search to find full span
 	    if ((cr->vEnd == end) && (end < virtSeqBaseCount))
 		{
 		sizeWanted = saveSizeWanted; 
 		goto try_again;
 		}
 	    }
 	else
 	    {
-	    //warn("nearest found vStart=%ld vEnd=%ld", cr->vStart, cr->vEnd); // DEBUG REMOVE
-	    // are we dangling off the start, need to expand search to find full span
+	    // if dangling off the start, need to expand search to find full span
 	    if ((cr->vStart == start) && (start > 0)) 
 		{
 		sizeWanted = saveSizeWanted; 
 		goto try_again;
 		}
 	    }
 	if (cr->vStart < 0)
 	    cr->vStart = 0;
 	if (cr->vEnd > virtSeqBaseCount)
 	    cr->vEnd = virtSeqBaseCount;
 	}
     else
 	{ 
 	// if none found, do we just return -1
 	cr->vStart = -1;
@@ -2325,31 +2299,30 @@
 void linkedFeaturesMoveWinEnd(long exonEnd, long bufferToEdge, long newWinSize, long *pNewWinStart, long *pNewWinEnd)
 /* A function used by linkedFeaturesNextPrevItem to make that function */
 /* easy to read. Move the window so that the end of the exon in question */
 /* is near the end of the browser window. */
 {
 *pNewWinEnd = exonEnd + bufferToEdge;
 if (*pNewWinEnd > virtSeqBaseCount)
     *pNewWinEnd = virtSeqBaseCount;
 *pNewWinStart = *pNewWinEnd - newWinSize;
 }
 
 boolean linkedFeaturesNextPrevItem(struct track *tg, struct hvGfx *hvg, void *item, int x, int y, int w, int h, boolean next)
 /* Draw a mapBox over the arrow-button on an *item already in the window*. */
 /* Clicking this will do one of several things: */
 {
-//warn("virtMode=%d next=%d winStart=%d winEnd=%d", virtMode, next, winStart, winEnd); // DEBUG REMOVE
 boolean result = FALSE;
 struct linkedFeatures *lf = item;
 struct simpleFeature *exons = lf->components;
 struct simpleFeature *exon = exons;
 char *nextExonText;
 char *prevExonText;
 long newWinSize = virtWinEnd - virtWinStart;
 long bufferToEdge = 0.05 * newWinSize;
 long newWinStart, newWinEnd;
 int numExons = 0;
 int exonIx = 0;
 struct slRef *exonList = NULL, *ref;
 if (startsWith("chain", tg->tdb->type) || startsWith("lrg", tg->tdb->track))
     {
     nextExonText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "nextExonText", "Next Block");
@@ -2398,54 +2371,49 @@
      || (!next && exon->start < winEnd  ))
 	{
 	cr->chrom = chromName;
 	cr->start = exon->start;
 	cr->end = exon->end;
 	}
     else
 	{
 	cr->skipIt = TRUE;
 	}
     slAddHead(&crList, cr);
     }
 slReverse(&crList);
 
 // convert entire list of ranges to virt coords in parallel.
-//warn("translate gene in parallel");  // DEBUG REMOVE
+// translate gene parts in parallel
 linkedFeaturesNextPrevExonFind(tg, next, crList);
 
 if ((numExons + 1) != slCount(crList))
     errAbort("Unexpected error in linkedFeaturesNextPrevItem: numExons=%d + 1 != slCount(crList)=%d", numExons, slCount(crList));
 
 // translate tall
 cr = crList;
 long xTallStart = cr->vStart, xTallEnd = cr->vEnd;
-//warn("tall next=%d lf->tallStart=%d lf->tallEnd=%d xTallStart=%ld xTallEnd=%ld skipIt=%d", 
-    //next, lf->tallStart, lf->tallEnd, xTallStart, xTallEnd, cr->skipIt);  // DEBUG REMOVE
-
 
 for (ref = exonList, cr=crList->next, exonIx = 0; ref != NULL; ref = ref->next, cr=cr->next, exonIx++)
     {
     char mouseOverText[256];
     boolean bigExon = FALSE;
     boolean revStrand = (lf->orientation == -1);
     exon = ref->val;
 
     // translate exon
     long xExonStart = cr->vStart, xExonEnd = cr->vEnd;
-    //warn("exon exonIx=%d next=%d exon->start=%d exon->end=%d xExonStart=%ld xExonEnd=%ld skipIt=%d", 
-	//exonIx, next, exon->start, exon->end, xExonStart, xExonEnd, cr->skipIt);  // DEBUG REMOVE
 
     if ((xExonEnd != -1) && ((xExonEnd - xExonStart) > (newWinSize - (2 * bufferToEdge))))
 	bigExon = TRUE;
     if (next && (xExonEnd != -1) && (xExonEnd > virtWinEnd))
 	/* right overhang (but left side of screen in reverse-strand-display) */
 	{
 	if (xExonStart < virtWinEnd)
 	    {
 	    /* not an intron hanging over edge. */
 	    if ((xTallEnd != -1) && (xTallEnd > virtWinEnd) && (xTallEnd < xExonEnd) && (xTallEnd > xExonStart))
 		linkedFeaturesMoveWinEnd(xTallEnd, bufferToEdge, newWinSize, &newWinStart, &newWinEnd);
 	    else
 		linkedFeaturesMoveWinEnd(xExonEnd, bufferToEdge, newWinSize, &newWinStart, &newWinEnd);
 	    }
 	else if (bigExon)
@@ -2658,61 +2626,60 @@
 	}
     else // done with old, starting new
 	{
 	doNew = TRUE;
 	}
     }
 
 return resultList;
 }
 
 struct virtRange 
     {
     struct virtRange *next;
     long vStart;
     long vEnd;
-    char *item;  // DEBUG REMOVE
+    char *item;
     };
 
 int vrCmp(const void *va, const void *vb)
 /* Compare to sort based on chromStart. */
 {
 const struct virtRange *a = *((struct virtRange **)va);
 const struct virtRange *b = *((struct virtRange **)vb);
 long dif = a->vStart - b->vStart;
 if (dif > 0) return 1;
 if (dif < 0) return -1;
 return 0;
 }
 
 int vrCmpEnd(const void *va, const void *vb)
 /* Compare to sort based on chromEnd. */
 {
 const struct virtRange *a = *((struct virtRange **)va);
 const struct virtRange *b = *((struct virtRange **)vb);
 long dif = a->vEnd - b->vEnd;
 if (dif > 0) return 1;
 if (dif < 0) return -1;
 return 0;
 }
 
 
 void linkedFeaturesLabelNextPrevItem(struct track *tg, boolean next)
 /* Default next-gene function for linkedFeatures.  Changes winStart/winEnd
  * and updates position in cart. */
 {
-//warn("got here linkedFeaturesLabelNextPrevItem virtWinStart=%ld virtWinEnd=%ld", virtWinStart, virtWinEnd); // DEBUG REMOVE
 
 long start = virtWinStart;
 long end = virtWinEnd;
 long size = virtWinBaseCount;
 long sizeWanted = size;
 long bufferToEdge;
 struct virtRange *vrList = NULL;
 
 /* If there's stuff on the screen, skip past it. */
 /* If not, skip to the edge of the window. */
 if (next)
     {
     start = end;
     end = start + size;
     if (end > virtSeqBaseCount)
@@ -2724,60 +2691,56 @@
     start = end - size;
     if (start < 0)
 	start = 0;
     }
 size = end - start;
 
 struct hash *hash = newHash(8);
 boolean firstTime = TRUE;
 
 /* Now it's time to do the search. */
 if (end > start)
     // GALT TODO BIGNUM == 0x3fffffff which is about 1 billion?
     for ( ; sizeWanted > 0 && sizeWanted < BIGNUM; )  
 	{
 
-	//warn("Expanding search window to start=%ld end=%ld size=%ld sizeWanted=%ld", start, end, size, sizeWanted); // DEBUG REMOVE
+	// Expanding search window to start, end, size, sizeWanted
 
 	// include the original window so we can detect overlap with it.
 	long xStart = start, xEnd = end;
 	if (firstTime)
 	    {
 	    firstTime = FALSE;
 	    if (next)
 		{
 		xStart = virtWinStart;
 		}
 	    else
 		{
 		xEnd = virtWinEnd;
 		}
 	    }
 
 	struct window *windows = makeWindowListFromVirtChrom(xStart, xEnd);
 
 	// To optimize when using tiny exon-like regions, merge nearby regions.
 	struct window *mergedWindows = makeMergedWindowList(windows);
 
-
-	//warn("#WINDOWS READ=%d mergedWindows=%d", slCount(windows), slCount(mergedWindows)); // DEBUG REMOVE
-
 	struct window *mw;
 	for(mw=mergedWindows; mw; mw=mw->next)
-	    {  // DEBUG TEST
+	    {
 
-	    //warn("WINDOW %ld-%ld %s:%d-%d", w->virtStart, w->virtEnd, w->chromName, w->winStart, w->winEnd); // DEBUG REMOVE
 	    struct bed *items = NULL;
 
 #ifndef GBROWSE
 	    if (sameWord(tg->table, WIKI_TRACK_TABLE))
 		items = wikiTrackGetBedRange(tg->table, mw->chromName, mw->winStart, mw->winEnd);
 	    else if (sameWord(tg->table, "gvPos"))
 		items = loadGvAsBed(tg, mw->chromName, mw->winStart, mw->winEnd);
 	    else if (sameWord(tg->table, "oreganno"))
 		items = loadOregannoAsBed(tg, mw->chromName, mw->winStart, mw->winEnd);
 	    else if (tg->isBigBed)
 		items = loadBigBedAsBed(tg, mw->chromName, mw->winStart, mw->winEnd);
 	    else
 #endif /* GBROWSE */
 		{
 		if (isCustomTrack(tg->table))
@@ -2795,131 +2758,99 @@
 		item->next = NULL;
 
 
 		struct window *w;
 		for(w=windows; w; w=w->next)
 		    {
 
 		    // item and region overlap?
 		    if ((item->chromEnd > w->winStart) && (w->winEnd > item->chromStart)) // overlap
 			{ // clip item to region
 			int s = max(w->winStart, item->chromStart); 
 			int e = min(w->winEnd, item->chromEnd);
 			long vs = w->virtStart + (s - w->winStart);
 			long ve = w->virtEnd - (w->winEnd - e);
 
-			//warn("item->name=%s item->chrom=%s item->chromStart=%d item->chromEnd=%d vs=%ld ve=%ld", 
-			    //item->name, item->chrom, item->chromStart, item->chromEnd, vs, ve);  // DEBUG REMOVE
-
 			// NOTE TODO should this key string code should be copied from the pack routine?
 			//  When I tried the pack code, mapItemName method was crashing, not sure why.
 			char key[1024];
 			safef(key, sizeof key, "%s:%d-%d %s", item->chrom, item->chromStart, item->chromEnd, item->name);
 
-			//warn("hash key=%s", key); // DEBUG REMOVE
-
 			struct hashEl *hel = hashLookup(hash, key);
 			struct virtRange *vr;
 			if (hel)
 			    { // if existing, extend its range
 			    vr = hel->val;
 			    vr->vStart = min(vs, vr->vStart);
 			    vr->vEnd = max(ve, vr->vEnd);
-			    //warn("updating vr, new values vr->vStart=%ld vr->vEnd=%ld", vr->vStart, vr->vEnd); // DEBUG REMOVE
 			    }
 			else
 			    { // create new vr
-			    //warn("creating new vr vs=%ld ve=%ld", vs, ve); // DEBUG REMOVE
 			    AllocVar(vr);
 			    vr->vStart = vs;
 			    vr->vEnd = ve;
-			    vr->item = cloneString(item->name); // DEBUG REMOVE
+			    vr->item = cloneString(item->name);
 			    vr->next = NULL;
 			    hashAdd(hash, key, vr);
 			    }
 			
 			}
 		    }
 		bedFree(&item);
 		}
 	    
 
 	    }
 
 	slFreeList(&mergedWindows);
 	slFreeList(&windows);
 
 	vrList = NULL;
-	//warn("create a list of vrs from hash");  // DEBUG REMOVE
 	// create a list of vrs from hash
 	struct hashCookie cookie = hashFirst(hash);
 	struct hashEl *hel;
 	while ((hel = hashNext(&cookie)) != NULL)
 	    {
 	    slAddHead(&vrList, hel->val);
 	    //hel->val = NULL; // keep for reuse
 	    }
-	//warn("about to slReverse vrList from hash");  // DEBUG REMOVE
 	slReverse(&vrList);  // probably not needed.
     
-
-	/*
-	{  // DEBUG REMOVE
-	warn("VR List");
-	struct virtRange *vr;
-	for(vr=vrList; vr; vr=vr->next)
-	    warn("vr->vStart=%ld vr->vEnd=%ld", vr->vStart, vr->vEnd);
-	
-	}
-	*/
-
-    
 	/* If we got something, or weren't able to search as big as we wanted to */
 	/* (in case we're at the end of the chrom).  */
 	if (vrList != NULL || (size < sizeWanted))
 	    {
 	    /* Remove the ones that were on the original screen. */
 	    struct virtRange *vr;
 	    struct virtRange *goodList = NULL;
 	    while ((vr = slPopHead(&vrList)) != NULL)
 		{
 		vr->next = NULL;
 		if ((vr->vEnd > virtWinStart) && (virtWinEnd > vr->vStart))
 		    {
 		    }
 		else
 		    slAddHead(&goodList, vr);
 		}
 	    if (goodList)
 		{
 		slReverse(&goodList);
 		vrList = goodList;
-		//warn("vrList=goodList"); // DEBUG REMOVE
 		break;
 		}
 	    }
 
-	/*
-	{  // DEBUG REMOVE
-	warn("VR List after filtering out ones on the original screen.");
-	struct virtRange *vr;
-	for(vr=vrList; vr; vr=vr->next)
-	    warn("vr->vStart=%ld vr->vEnd=%ld", vr->vStart, vr->vEnd);
-	
-	}
-	*/
-
 try_again:    
 	sizeWanted *= 2;
 	if (next)
 	    {
 	    start = end;
 	    end += sizeWanted;
 	    if (end > virtSeqBaseCount)
 		end = virtSeqBaseCount;
 	    }
 	else
 	    {
 	    end = start;
 	    start -= sizeWanted;
 	    if (start < 0)
 		start = 0;
@@ -2937,120 +2868,93 @@
 	    }
 
 	}
 
 
 /* Finally, we got something. */
 int saveSizeWanted = sizeWanted;
 sizeWanted = virtWinEnd - virtWinStart;  // resetting sizeWanted back to the original windows span size
 bufferToEdge = (long)(0.05 * (float)sizeWanted);
 if (vrList)
     {
     struct virtRange *vr = NULL;
     if (next)
 	{
 	slSort(&vrList, vrCmp);
-	/* //final list
-	{  // DEBUG REMOVE
-	warn("Final good VR List");
-	struct virtRange *vr;
-	for(vr=vrList; vr; vr=vr->next)
-	    warn("vr->vStart=%ld vr->vEnd=%ld vr->item=%s", vr->vStart, vr->vEnd, vr->item);
-	
-	}
-	*/
 	vr = vrList;  // first one is nearest
-	//warn("nearest found vr->vStart=%ld vr->vEnd=%ld vr->item=%s", vr->vStart, vr->vEnd, vr->item); // DEBUG REMOVE
-
-	// are we dangling off the end, need to expand search to find full span
+	// if dangling off the end, need to expand search to find full span
         if ((vr->vEnd == end) && (end < virtSeqBaseCount))
 	    {
 	    sizeWanted = saveSizeWanted; 
 	    goto try_again;
 	    }
-	//warn("sizeWanted=%ld, bufferToEdge=%ld", sizeWanted, bufferToEdge);  // DEBUG REMOVE
 	if (vr->vEnd + bufferToEdge - sizeWanted < virtWinEnd)
 	    {
-	    //warn("case 1, item end plus 5%% buffer within one screen width ahead"); // DEBUG REMOVE
+	    // case 1, item end plus 5%% buffer within one screen width ahead
 	    virtWinEnd = vr->vEnd + bufferToEdge;
 	    virtWinStart = virtWinEnd - sizeWanted;
 	    }
 	else if (vr->vStart + bufferToEdge - sizeWanted < virtWinEnd)
 	    {
-	    //warn("case 2, (puzzling) item start plus 5%% buffer within one screen width ahead"); // DEBUG REMOVE
+	    // case 2, (puzzling) item start plus 5%% buffer within one screen width ahead
 	    virtWinEnd = vr->vStart + bufferToEdge;
 	    virtWinStart = virtWinEnd - sizeWanted;
 	    }
 	else
 	    {
-	    //warn("case 3, default. shift window to item start minus 5%% buffer"); // DEBUG REMOVE
+	    // case 3, default. shift window to item start minus 5%% buffer
 	    virtWinStart = vr->vStart - bufferToEdge;
 	    virtWinEnd = virtWinStart + sizeWanted;
 	    }
 	}
     else
 	{
 	slSort(&vrList, vrCmpEnd);
 	slReverse(&vrList);
-	/*
-	//final list
-	{  // DEBUG REMOVE
-	warn("Final good VR List");
-	struct virtRange *vr;
-	for(vr=vrList; vr; vr=vr->next)
-	    warn("vr->vStart=%ld vr->vEnd=%ld vr->item=%s", vr->vStart, vr->vEnd, vr->item);
-	
-	}
-	*/
 	vr = vrList;  // first one is nearest
-	//warn("nearest found vr->vStart=%ld vr->vEnd=%ld vr->item=%s", vr->vStart, vr->vEnd, vr->item); // DEBUG REMOVE
-
-	// are we dangling off the start, need to expand search to find full span
+	// if dangling off the start, need to expand search to find full span
         if ((vr->vStart == start) && (start > 0)) 
 	    {
 	    sizeWanted = saveSizeWanted; 
 	    goto try_again;
 	    }
-	//warn("sizeWanted=%ld, bufferToEdge=%ld", sizeWanted, bufferToEdge);  // DEBUG REMOVE
 	if (vr->vStart - bufferToEdge + sizeWanted > virtWinStart)
 	    {
-	    //warn("case 1, item start minus 5%% buffer within one screen width behind"); // DEBUG REMOVE
+	    // case 1, item start minus 5%% buffer within one screen width behind
 	    virtWinStart = vr->vStart - bufferToEdge;
 	    virtWinEnd = virtWinStart + sizeWanted;
 	    }
         else if (vr->vEnd - bufferToEdge + sizeWanted > virtWinStart)
 	    {
-	    //warn("case 2, (puzzling) item end minus 5%% buffer within one screen width behind"); // DEBUG REMOVE
+	    // case 2, (puzzling) item end minus 5%% buffer within one screen width behind
 	    virtWinStart = vr->vEnd - bufferToEdge;
 	    virtWinEnd = virtWinStart + sizeWanted;
 	    }
         else
 	    {
-	    //warn("case 3, default. shift window to item end minus 5%% buffer"); // DEBUG REMOVE
+	    // case 3, default. shift window to item end minus 5%% buffer
 	    virtWinEnd = vr->vEnd + bufferToEdge;
 	    virtWinStart = virtWinEnd - sizeWanted;
 	    }
 	}
     if (virtWinEnd > virtSeqBaseCount)
 	virtWinEnd = virtSeqBaseCount;
     if (virtWinStart < 0)
 	virtWinStart = 0;
 
     virtWinBaseCount = virtWinEnd - virtWinStart;
 
-    //warn("RESULT: virtWinStart=%ld virtWinEnd=%ld virtWinBaseCount=%ld",virtWinStart,virtWinEnd,virtWinBaseCount); // DEBUG REMOVE
-
     }
 
 // Because nextItem now gets called earlier (in tracksDisplay), 
 // before trackList gets duplicated in trackForm,
 // we do not want this track to have open handles and resources
 // be duplicated later for each window. Close resources as needed.
 tg->items = NULL;
 #ifndef GBROWSE
 if (tg->isBigBed)
     bbiFileClose(&tg->bbiFile);
 #endif /* GBROWSE */
 
 // free the hash and its values?
 struct hashCookie cookie = hashFirst(hash);
 struct hashEl *hel;
@@ -4189,60 +4093,57 @@
     // Do for all windows
     struct track *tgSave = tg; 
     for(tg=tgSave; tg; tg=tg->nextWindow)
 	{		    
 	for (sn = tg->ss->nodeList; sn != NULL; sn = sn->next)
 	    // do not count items with label turned off as they are dupes anyways.
 	    if (sn->row >= overflowRow && !sn->noLabel) 
 		overflowCount++;
 	}
     tg = tgSave;
     assert(hvgSide != NULL);
     hvGfxUnclip(hvgSide);
     hvGfxSetClip(hvgSide, leftLabelX, yOff, insideWidth, tg->height);
     char nameBuff[SMALLBUF];
     safef(nameBuff, sizeof(nameBuff), "Last Row: %d", overflowCount);
-    //warn("[%s] overflowRow %d window %lu", nameBuff, overflowRow, (unsigned long) currentWindow);  // DEBUG REMOVE
     mgFontStringWidth(font, nameBuff);
     hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, tg->lineHeight,
                    color, font, nameBuff);
     hvGfxUnclip(hvgSide);
     hvGfxSetClip(hvgSide, insideX, yOff, insideWidth, tg->height);
     }
 /* restore state */
 tg->limitedVis = origVis;
 tg->heightPer = origHeightPer;
 tg->lineHeight = origLineHeight;
 }
 
 static void genericDrawItem(struct track *tg, struct spaceNode *sn,
                             struct hvGfx *hvg, int xOff, int yOff, int width,
                             MgFont *font, Color color, Color labelColor, enum trackVisibility vis,
                             double scale, boolean withLeftLabels)
 /* draw one non-overflow item */
 {
 struct slList *item = sn->val;
 int s = tg->itemStart(tg, item);
 int e = tg->itemEnd(tg, item);
 int sClp = (s < winStart) ? winStart : s;
 int eClp = (e > winEnd)   ? winEnd   : e;
 int x1 = round((sClp - winStart)*scale) + xOff;
 int x2 = round((eClp - winStart)*scale) + xOff;
 int textX = x1;
 
-//warn("genericDrawItem top x1=%d x2=%d xOff=%d insideX=%d insideWidth=%d", x1, x2, xOff, insideX, insideWidth); // DEBUG REMOVE
-
 if (tg->drawLabelInBox)
     withLeftLabels = FALSE;
 
 if (tg->itemNameColor != NULL)
     {
     color = tg->itemNameColor(tg, item, hvg);
     labelColor = color;
     if (withLeftLabels && isTooLightForTextOnWhite(hvg, color))
 	labelColor = somewhatDarkerColor(hvg, color);
     }
 
 // get y offset for item in pack mode
 int yRow = 0;
 if (tg->ss && tg->ss->rowSizes != NULL)
     {
@@ -4294,40 +4195,36 @@
             {
             int boxStart = leftLabelX + leftLabelWidth - 2 - nameWidth;
             hvGfxBox(hvgSide, boxStart, y, nameWidth+1, tg->heightPer - 1, color);
             hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, tg->heightPer,
                         MG_WHITE, font, name);
             }
         else
             hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, tg->heightPer,
                         labelColor, font, name);
         hvGfxUnclip(hvgSide);
         hvGfxSetClip(hvgSide, insideX, yOff, insideWidth, tg->height);
         }
     else
         {
 
-	//warn("textX=%d y=%d nameWidth=%d name=%s insideX=%d insideWidth=%d", textX, y, nameWidth, name, insideX, insideWidth);  // DEBUG REMOVE
-	//warn("DEBUG hgfxSetClip fullInsideX=%d yOff=%d fullInsideWidth=%d tg->height=%d", fullInsideX, yOff, fullInsideWidth, tg->height);  // DEBUG REMOVE
-	
 	// shift clipping to allow drawing label to left of currentWindow
 	int pdfSlop=nameWidth/5;
         hvGfxUnclip(hvg);
         hvGfxSetClip(hvg, textX-1-pdfSlop, y, nameWidth+1+pdfSlop, tg->heightPer);
         if(drawNameInverted)
             {
-	    //warn("drawNameInverted"); // DEBUG REMOVE
             hvGfxBox(hvg, textX - 1, y, nameWidth+1, tg->heightPer-1, color);
             hvGfxTextRight(hvg, textX, y, nameWidth, tg->heightPer, MG_WHITE, font, name);
             }
         else
             hvGfxTextRight(hvg, textX, y, nameWidth, tg->heightPer, labelColor, font, name);
         hvGfxUnclip(hvg);
         hvGfxSetClip(hvg, insideX, yOff, insideWidth, tg->height);
         }
     }
 if (!tg->mapsSelf)
     {
     int w = x2-textX;
     /* Arrows? */
     if (w > 0)
         {