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

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 743d1c0..ca571e3 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -620,69 +620,65 @@
 struct track *ideoTrack = NULL;
 MgFont *font = tl.font;
 char *mapName = "ideoMap";
 struct hvGfx *hvg;
 boolean doIdeo = TRUE;
 int ideoWidth = round(.8 *tl.picWidth);
 int ideoHeight = 0;
 int textWidth = 0;
 struct tempName pngTn;
 boolean nukeIdeoFromList = FALSE;
 if (ideoTn == NULL)
     ideoTn = &pngTn;   // not returning value
 
 ideoTrack = chromIdeoTrack(*pTrackList);
 
-//warn("makeChromIdeoImage ideoTrack=%lu ideoTrack->track=%s", (unsigned long) ideoTrack, ideoTrack ? ideoTrack->track : ""); // DEBUG REMOVE
-
 /* If no ideogram don't draw. */
 if(ideoTrack == NULL)
     {
     doIdeo = FALSE;
     }
 else if(trackImgOnly && !ideogramToo)
     {
     doIdeo = FALSE;
     }
 else
     {
-    //warn("makeChromIdeoImage about to remove track from group and tracklist"); // DEBUG REMOVE
     /* Remove the track from the group and track list. */
     removeTrackFromGroup(ideoTrack);
     slRemoveEl(pTrackList, ideoTrack);
     nukeIdeoFromList = TRUE;
 
     /* Fix for hide all button hiding the ideogram as well. */
     if(withIdeogram && ideoTrack->items == NULL)
 	{
 	ideoTrack->visibility = tvDense;
 	ideoTrack->loadItems(ideoTrack);
 	}
     limitVisibility(ideoTrack);
 
     /* If hidden don't draw. */
     if(ideoTrack->limitedVis == tvHide || !withIdeogram)
         doIdeo = FALSE;
     }
 // TODO use DIV in future (can update entire div at once in hgTracks.js)
 //hPrintf("<DIV id='chromIdeoDiv'>\n"); 
 // FYI from testing, I see that there is code that inserts warning error messages
 //  right before ideoMap, so any changes to that name or adding the DIV would require
 //  updating the warning-insertion target name.
 if(doIdeo)
     {
-    //warn("makeChromIdeoImage doIdeo = TRUE"); // DEBUG REMOVE
     char startBand[16];
     char endBand[16];
     char title[64];  // was 32
     startBand[0] = endBand[0] = '\0';
     fillInStartEndBands(ideoTrack, startBand, endBand, sizeof(startBand));
     /* Start up client side map. */
     if (!psOutput)
         hPrintf("<MAP Name=%s>\n", mapName);
     /* Draw the ideogram. */
     ideoHeight = gfxBorder + ideoTrack->height;
     if (psOutput)
         {
         trashDirFile(ideoTn, "hgtIdeo", "hgtIdeo", ".ps");
         hvg = hvGfxOpenPostScript(ideoWidth, ideoHeight, ideoTn->forCgi);
         }
@@ -1421,50 +1417,46 @@
     portWidth = portWidth-gfxBorder-insideX;
     }
 int arrowWidth = insideHeight;
 int arrowButtonWidth = arrowWidth + 2 * NEXT_ITEM_ARROW_BUFFER;
 int rightButtonX = portX + portWidth - arrowButtonWidth - 1;
 char buttonText[256];
 Color fillColor = lightGrayIndex();
 labelColor = blackIndex();
 hvGfxNextItemButton(hvg, rightButtonX + NEXT_ITEM_ARROW_BUFFER, y, arrowWidth, arrowWidth,
                     labelColor, fillColor, TRUE);
 hvGfxNextItemButton(hvg, portX + NEXT_ITEM_ARROW_BUFFER, y, arrowWidth, arrowWidth,
                     labelColor, fillColor, FALSE);
 
 safef(buttonText, ArraySize(buttonText), "hgt.prevItem=%s", track->track);
 
-// warn("portX=%d y+1=%d portWidth=%d arrowButtonWidth=%d track=%s", portX, y+1, portWidth, arrowButtonWidth, track->track); // DEBUG REMOVE
-
 mapBoxReinvoke(hvg, portX, y + 1, arrowButtonWidth, insideHeight, track, FALSE,
                NULL, 0, 0, (revCmplDisp ? "Next item" : "Prev item"), buttonText);
 
 #ifdef IMAGEv2_SHORT_TOGGLE
 char *label = (theImgBox ? track->longLabel : parentTrack->longLabel);
 int width = portWidth - (2 * arrowButtonWidth);
 int x = portX + arrowButtonWidth;
 // make toggle cover only actual label
 int size = mgFontStringWidth(font,label) + 12;  // get close enough to the label
 if (width > size)
     {
     x += width/2 - size/2;
     width = size;
     }
 mapBoxToggleVis(hvg, x, y + 1, width, insideHeight, (theImgBox ? track : parentTrack));
 #else///ifndef IMAGEv2_SHORT_TOGGLE
-//warn("portX+arrowButtonWidth=%d y+1=%d portWidth-(2*arrowButtonWidth)=%d arrowButtonWidth=%d track=%s", 
-  //portX + arrowButtonWidth, y+1, portWidth - (2 * arrowButtonWidth), arrowButtonWidth, track->track); // DEBUG REMOVE
 mapBoxToggleVis(hvg, portX + arrowButtonWidth, y + 1, portWidth - (2 * arrowButtonWidth),
                 insideHeight, (theImgBox ? track : parentTrack));
 #endif///ndef IMAGEv2_SHORT_TOGGLE
 
 // use the last window globals instead of the first 
 struct window *w=windows;
 while(w->next)
     w = w->next;
 setGlobalsFromWindow(w); // use last window
 
 safef(buttonText, ArraySize(buttonText), "hgt.nextItem=%s", track->track);
 mapBoxReinvoke(hvg, portX + portWidth - arrowButtonWidth, y + 1, arrowButtonWidth, insideHeight,
                track, FALSE, NULL, 0, 0, (revCmplDisp ? "Prev item" : "Next item"), buttonText);
 
 setGlobalsFromWindow(windows); // restore first window
@@ -2085,44 +2077,41 @@
 // store highlight information
 {
 char *db;
 char *chrom;
 long chromStart;
 long chromEnd;
 char *hexColor;
 };
 
 struct highlightVar *parseHighlightInfo()
 // Parse highlight info from cart var
 // db.chrom:start-end#hexColor
 {
 struct highlightVar *h = NULL;
 char *highlightDef = cartOptionalString(cart, "highlight");
-//warn("parseHighlightInfo highlight=%s", highlightDef); // DEBUG REMOVE
 if(highlightDef)
     {
     AllocVar(h);
     h->db     = cloneNextWordByDelimiter(&highlightDef,'.');
     h->chrom  = cloneNextWordByDelimiter(&highlightDef,':');
     // long to handle virt chrom coordinates
     h->chromStart = atol(cloneNextWordByDelimiter(&highlightDef,'-'));
     h->chromEnd   = atol(cloneNextWordByDelimiter(&highlightDef,'#'));
     h->chromStart--; // Not zero based
     if (highlightDef && *highlightDef != '\0')
 	h->hexColor = cloneString(highlightDef);
-    //verbose(1, "DEBUG GALT highlightRegion() db=%s chrom=%s chromStart=%ld chromEnd=%ld virtChromName=%s winStart=%ld winEnd=%ld\n",
-	//h->db, h->chrom, h->chromStart, h->chromEnd, virtChromName, virtWinStart, virtWinEnd); // DEBUG REMOVE
     }
 return h;
 }
 
 void highlightRegion(struct cart *cart, struct hvGfx *hvg, int imagePixelHeight)
 // Highlights a region in the image.  Only done if theImgBox is not defined.
 // Thus it is done for ps/pdf and view image but the hgTracks image is highlighted via js
 {
 struct highlightVar *h = parseHighlightInfo();
 
 if(h && theImgBox == NULL) // Only highlight region when imgBox is not used. (pdf and show-image)
     {
     if (virtualSingleChrom()) // DISGUISE VMODE
 	{
 	if ((h->db && sameString(h->db, database))
@@ -2192,32 +2181,30 @@
 
 //void menuBarAppendExtTools() 
 ///* printf a little javascript that adds entries to a menu */
 //{
 //    char url[SMALLBUF];
 //    safef(url,ArraySize(url),"hgTracks?%s=%s&hgt.redirectTool=crispor",cartSessionVarName(), cartSessionId(cart));
 //    printf("<script>\n");
 //    printf("jQuery(document).ready( function() {\n");
 //    domAddMenu("view", "sendto", "Send to");
 //    domAppendToMenu("sendto", url, "Tefor CRISPR sites");
 //    printf("});\n");
 //    printf("</script>\n");
 //}
 
 
-//--- GALT
-
 char *rgbColorToString(struct rgbColor color)
 /* make rgbColor into printable string */
 {
 char buf[256];
 safef(buf, sizeof buf, "rgbColor r:%d g:%d b:%d", color.r, color.g, color.b);
 return cloneString(buf);
 }
 
 char *trackDumpString(struct track *track)
 /* Write out info on track to string */
 {
 struct dyString *dy = dyStringNew(256);
 
 dyStringPrintf(dy, "next: %lu\n", (unsigned long)track->next);
 //    struct track *next;   /* Next on list. */
@@ -2569,114 +2556,107 @@
 char *dash = strchr(vPos, '-');
 if (!dash)
     errAbort("position has no dash");
 *colon = 0;
 *dash = 0;
 *pChrom = cloneString(vPos);
 *pStart = atoi(colon+1) - 1;
 *pEnd = atoi(dash+1);
 }
 
 char *disguisePositionVirtSingleChrom(char *position) // DISGUISE VMODE
 /* Hide the virt position, convert to real single chrom span.
  * position should be virt chrom span. 
  * Can handle anything in the virt single chrom. */
 {   
-//warn("disguisePosition position="+position); // DEBUG REMOVE
 /* parse Virt position */
 char *chrom = NULL;
 long start = 0;
 long end = 0;
 parseVPosition(position, &chrom, &start, &end);
 if (!sameString(chrom, "virt"))
     return position; // return original
-//warn("start="+start+" end="+end); // DEBUG REMOVE
 struct window *windows = makeWindowListFromVirtChrom(start, end);
 char *nonVirtChromName = windows->chromName;
 if (!sameString(nonVirtChromName, chromName))
     return position; // return original
 int nonVirtWinStart  = windows->winStart;
 int nonVirtWinEnd    = windows->winEnd;
 struct window *w;
 for (w=windows->next; w; w=w->next)
     {
-    //warn("w->chromName=%s w->winStart=%d w->winEnd=%d",w->chromName, w->winStart, w->winEnd); // DEBUG REMOVE
     if (!sameString(w->chromName, nonVirtChromName))
 	return position; // return original
     if (w->winEnd < nonVirtWinEnd)
 	return position; // return original
     nonVirtWinEnd = w->winEnd;
     }
 char nvPos[256];
 safef(nvPos, sizeof nvPos, "%s:%d-%d", nonVirtChromName, nonVirtWinStart+1, nonVirtWinEnd);
 slFreeList(&windows);
 return cloneString(nvPos);
 }
 
 
 
 char *undisguisePosition(char *position) // UN-DISGUISE VMODE
 /* Find the virt position
  * position should be real chrom span. 
  * Limitation: can only convert things in the current windows set. */
 {   
-//warn("undisguisePosition position="+position); // DEBUG REMOVE
 /* parse NonVirt position */
 char *chrom = NULL;
 int start = 0;
 int end = 0;
 parseNVPosition(position, &chrom, &start, &end);
 if (!sameString(chrom, chromName))
     return position; // return original
 long newStart = -1;
 long newEnd = -1;
 struct window *lastW = NULL;
 struct window *w = NULL;
-//warn("start="+start+" end="+end); // DEBUG REMOVE
 for (w = windows; w; w=w->next)
     {
     //  double check chrom is same thoughout all windows, otherwise warning, return original value
     if (!sameString(w->chromName, chromName))
 	{
 	return position; // return original
 	}
     // check that the regions are ascending and non-overlapping
     if (lastW && w->winStart < lastW->winEnd)
 	{
 	return position; // return original
 	}
     // overlap with position?
     //  if intersection, 
     if (w->winEnd > start && end > w->winStart) 
 	{
 	int s = max(start, w->winStart);
 	int e = min(end, w->winEnd);
 	long cs = s - w->winStart + w->virtStart;
 	long ce = e - w->winStart + w->virtStart;
-	//warn("cs="+cs+" ce="+ce); // DEBUG REMOVE
 	if (newStart == -1)
 	    newStart = cs;
 	newEnd = ce;
 	}
     lastW = w;
    }
 if (newStart == -1) // none of the windows intersected with the position
     return position; // return original  
 //  return new virt undisguised position as a string
 char newPos[1024];
 safef (newPos, sizeof newPos, "virt:%ld-%ld", (newStart+1), newEnd);
-//warn("undisguisePosition newPos="+newPos); // DEBUG REMOVE
 return cloneString(newPos);
 }
 
 
 char *windowsSpanPosition()
 /* Return a position string that spans all the windows.
  * Windows should be on same chrom and ascending and non-overlapping.*/
 {
 char buf[256];
 char *chromName = windows->chromName;
 int start = windows->winStart;
 struct window *w = windows, *last = NULL;
 while(w->next) // find last window
     {
     last = w;
@@ -2747,72 +2727,69 @@
 	    }
 	}
     v->start = virtRegion->start - leftWindowPadding;
     v->end = virtRegion->end + rightWindowPadding;
     if (v->start < 0)
 	v->start = 0;
     if (v->end >= chromSize)
 	v->end = chromSize;
     regionBases += (v->end - v->start);
     slAddHead(&newList, v);
 
     lastVirtRegion = virtRegion;
     lastChrom = virtRegion->chrom;
     ++regionCount;
     }
-//warn("After padding, %d regions", regionCount); // DEBUG REMOVE
 slReverse(&newList);
-virtRegionList = newList; // update new list -- TODO should the old one be freed? if so, the chrom name should use cloneString
+virtRegionList = newList; // update new list -- 
+// TODO should the old one be freed? if so, the chrom name should use cloneString
 }
 
 
 void makeVirtChrom()
 /* build virtual chrom array from virt region list */
 {
 virtRegionCount = slCount(virtRegionList);
 AllocArray(virtChrom, virtRegionCount);
 struct virtRegion *v;
 int i = 0;
 long totalBases = 0;
 for(v=virtRegionList;v;v=v->next,++i)
     {
     virtChrom[i].virtPos = totalBases;
     virtChrom[i].virtRegion = v;
     totalBases += (v->end - v->start);
-    //warn("virtChrom[%d] .virtPos=%ld", i, virtChrom[i].virtPos);  // DEBUG REMOVE
     }
 virtSeqBaseCount = totalBases;
 }
 
 void virtChromBinarySearch(long target, long *resultIndex, int *resultOffset)
 /* Do a binary search for the target position in the virtual chrom.
  * Return virtChrom Index and Offset if found.
  * Return -1 if target out of range. TODO maybe change to errAbort*/
 {
 //The binary search will either return match or out-of-range.
 long index = -1;
 int offset = -1;
 long a = 0; // start of the array
 long b = virtRegionCount - 1; // end of array where N = count of regions
 if (target >=0 && target < virtSeqBaseCount)
     {
     while(1)
 	{
 	long c = (a + b) / 2;
 
-	//warn("target=%ld a=%ld b=%ld c=%ld virtRegionCount=%d", target, a, b, c, virtRegionCount); // DEBUG REMOVE
-
 	if (a > b)
 	    {
 	    index = b;
 	    break;
 	    }
 	else if (target == virtChrom[c].virtPos)
 	    {
 	    // (exact match)
 	    index = c;
 	    break;
 	    }
 	else if (target > virtChrom[c].virtPos)
 	    {
 	    a = c + 1;
 	    }
@@ -2880,32 +2857,30 @@
     errAbort("unexpected error. virtWinEnd=%ld out of range. virtSeqBaseCount=%ld", virtWinEnd, virtSeqBaseCount);
 if (virtWinEnd - virtWinStart < 1)
     errAbort("unexpected error. virtual window size < 1 base. virtWinStart=%ld virtWinEnd=%ld virtSeqBaseCount=%ld", virtWinStart, virtWinEnd, virtSeqBaseCount);
 long virtIndexStart;
 int  virtOffsetStart;
 virtChromBinarySearch(virtWinStart, &virtIndexStart, &virtOffsetStart);
 if (virtIndexStart == -1)
     errAbort("unexpected failure to find target virtWinStart %ld in virtChrom Array", virtWinStart);
 
 long virtIndexEnd;
 int  virtOffsetEnd;
 virtChromBinarySearch(virtWinEnd, &virtIndexEnd, &virtOffsetEnd);
 if (virtIndexEnd == -1)
     errAbort("unexpected failure to find target virtWinEnd %ld in virtChrom Array", virtWinEnd);
 
-//warn("after binary searches, virtIndexStart=%ld virtOffsetStart=%d , virtIndexEnd=%ld virtOffsetEnd=%d", virtIndexStart, virtOffsetStart, virtIndexEnd, virtOffsetEnd);  // DEBUG  REMOVE
-
 // create new windows list from virt chrom
 struct window *windows = NULL;
 long i = virtIndexStart;
 int winCount = 0;
 long basesInWindows = 0; // TODO not actually using this variable 
 for(i=virtIndexStart; i <= virtIndexEnd; ++i)
     {
     struct window *w;
     AllocVar(w);
     w->organism = organism; // obsolete
     w->database = database; // obsolete
     struct virtRegion *v = virtChrom[i].virtRegion;
     long virtPos = virtChrom[i].virtPos;
     w->chromName = v->chrom;
     if (i == virtIndexStart)
@@ -2960,47 +2935,43 @@
 	nonVirtWinEnd = w->winEnd;
     }
 // TODO Also consider preserving the original bases in windows width (with clipping).
 char nvPos[256];
 safef(nvPos, sizeof nvPos, "%s:%d-%d", nonVirtChromName, nonVirtWinStart+1, nonVirtWinEnd);
 return cloneString(nvPos);
 }
 
 char *nonVirtPositionFromHighlightPos()
 /* Must have created the virtual chrom first.
  * Currently just a hack to use windows,
  * use the (first) window(s) from that to get real chrom name start end */
 {
 struct highlightVar *h = parseHighlightInfo();
 
-//if (h)
-//    warn("remapHighlightPos h-> chrom=%s chromStart=%ld chromEnd=%ld", h->chrom, h->chromStart, h->chromEnd); // DEBUG REMOVE
-
 if (!(h && h->db && sameString(h->db, database) && sameString(h->chrom,"virt")))
     return NULL;
 
 struct window *windows = makeWindowListFromVirtChrom(h->chromStart, h->chromEnd);
 
 char *nonVirtChromName = windows->chromName;
 int nonVirtWinStart  = windows->winStart;
 int nonVirtWinEnd    = windows->winEnd;
 // Extending this through more of the windows,
 // if it is on the same chrom and maybe not too far separated.
 struct window *w;
 for (w=windows->next; w; w=w->next)
     {
-    //warn("w->chromName=%s w->winStart=%d w->winEnd=%d",w->chromName, w->winStart, w->winEnd); // DEBUG REMOVE
     if (sameString(w->chromName, nonVirtChromName) && w->winEnd > nonVirtWinEnd)
 	nonVirtWinEnd = w->winEnd;
     }
 // TODO Also consider preserving the original bases in windows width (with clipping).
 char nvPos[256];
 safef(nvPos, sizeof nvPos, "%s.%s:%d-%d#%s", h->db, nonVirtChromName, nonVirtWinStart+1, nonVirtWinEnd, h->hexColor);
 return cloneString(nvPos);
 }
 
 void allocPixelsToWindows()
 /* Allocate pixels to windows, sets insideWidth and insideX 
  *
  * TODO currently uses a strategy that places a window at a pixel location 
  * directly, because of round-off and missing small windows this can occasionally
  * lead to gaps not covered by any pixel.  Consider replacing it with something 
@@ -3009,56 +2980,41 @@
 {
 double pixelsPerBase = (double)fullInsideWidth / virtWinBaseCount; 
 long basesUsed = 0;
 int windowsTooSmall = 0;
 struct window **pWindows = &windows;
 struct window *window;
 int winCount = slCount(windows);
 for(window=windows;window;window=window->next)
     {
     int basesInWindow = window->winEnd - window->winStart; 
     int pixelsInWindow = 0.5 + (double)basesInWindow * pixelsPerBase; // should this round up ? + 0.5?
     window->insideWidth = pixelsInWindow;
     window->insideX = fullInsideX + basesUsed * pixelsPerBase;
     basesUsed += basesInWindow;
 
-    //warn("window x = %d  width = %d x + width=%d basesInWindow=%d", 
-	//window->insideX, window->insideWidth, window->insideX + window->insideWidth, basesInWindow); // DEBUG REMOVE
-
     if (pixelsInWindow < 1) // remove windows less than one pixel from the list
 	{
-	//if (windowsTooSmall < 5)
-	//    warn("window x = %d  width = %d x + width=%d", window->insideX, window->insideWidth, window->insideX + window->insideWidth);
 	*pWindows = window->next;
 	--winCount;
 	++windowsTooSmall;
 	}
     else
 	{
 	pWindows = &window->next;
 	}
     }
-//if (windowsTooSmall > 0)
-//    warn("Summary: %d windowsTooSmall: (pixelsInWindow < 1)", windowsTooSmall);
-
-//warn("winCount=%d slCount(windows)=%d #LessThan1Pixel=%d fullInsideWidth=%d virtWinBaseCount=%ld basesUsed=%ld", 
-    //winCount, slCount(windows), windowsTooSmall, fullInsideWidth, virtWinBaseCount, basesUsed);
-
-// DEBUG REMOVE:
-// nextExonArrows are working now 
-//if (winCount >= 2)
-//    withNextExonArrows = FALSE;	/* Display next exon navigation buttons near center labels? */
 }
 
 struct positionMatch *virtChromSearchForPosition(char *chrom, int start, int end, boolean findNearest)
 /* Search the virtual chrom for the query chrom, start, end position
  *
  * TODO GALT: Intially this can be a simple brute-force search of the entire virtChrom array.
  * 
  * However, this will need to be upgraded to using a rangeTree or similar structure
  * to rapidly return multiple regions that overlap the query position.
  * */
 {
 struct positionMatch *list=NULL, *p;
 int nearestRegion = -1;
 boolean nearestAfter = TRUE;
 int nearestDistance = INT_MAX;
@@ -3104,32 +3060,30 @@
     v = virtChrom[i].virtRegion;
     virtPos = virtChrom[i].virtPos;
     AllocVar(p);
     if (nearestAfter)
 	{
     	p->virtStart = virtPos;
 	p->virtEnd   = p->virtStart + (end - start);
 	}
     else
 	{
     	p->virtEnd = virtPos + (v->end - v->start);
 	p->virtStart = p->virtEnd - (end - start);
 	}
     if (p->virtEnd > virtSeqBaseCount)
 	p->virtEnd = virtSeqBaseCount;
-    //warn("findNearest: nearestRegion=%d nearestDistance=%d p->virtStart=%ld p->virtEnd=%ld ", 
-	//nearestRegion, nearestDistance, p->virtStart, p->virtEnd); // DEBUG REMOVE
     slAddHead(&list, p);
     }
 slReverse(&list);
 return list;
 }
 
 int matchVPosCompare(const void *elem1, const void *elem2)
 /* compare elements based on vPos */
 {
 const struct positionMatch *a = *((struct positionMatch **)elem1);
 const struct positionMatch *b = *((struct positionMatch **)elem2);
 if (a->virtStart == b->virtStart)
     errAbort("matchVPosCompare error should not happen: 2 elements being sorted have the same virtStart=%ld", a->virtStart);
 else if (a->virtStart > b->virtStart)
     return 1;
@@ -3195,33 +3149,30 @@
 	}
     if (!m)
 	break;
     lastStart = m->virtStart;
     lastEnd = m->virtEnd;
     lastM = m;
     }
 slReverse(&newList);
 return newList;
 }
 
 
 // ----------------------------------
 
 
-static void checkMaxWindowToDraw(struct track *tg); // forward declaration  // DEBUG REMOVE?
-
-
 void initVirtRegionsFromSOD1Hardwired()
 /* create a testing regionlist from SOD1 (uc002ypa.3) hardwired */
 {
 virtRegionList = NULL;
 char *chrom="chr21";
 //int exonStarts[] = {33031934,33036102,33038761,33039570,33040783};
 //int exonEnds[]   = {33032154,33036199,33038831,33039688,33041243};
 // BASE-level zoom in two 20 bp exons and their on-screen junction
 int exonStarts[] = {33032134,33036102};
 int exonEnds[]   = {33032154,33036122};
 int i;
 for(i=0; i<ArraySize(exonStarts); ++i)
     {
     struct virtRegion *v;
     AllocVar(v);
@@ -3299,31 +3250,30 @@
 char query[256];
 sqlSafef(query, sizeof(query), "select chrom, chromStart, chromEnd from %s where name='%s'", table, haplotypeId);
 sr = sqlGetResult(conn, query);
 row = sqlNextRow(sr);
 if (!row)
     {
     warn("no haplotype found for [%s]", haplotypeId);
     return FALSE;
     }
 char *haploChrom = cloneString(row[0]);
 int haploStart = sqlUnsigned(row[1]);
 int haploEnd   = sqlUnsigned(row[2]);
 sqlFreeResult(&sr);
 // what is the size of the alt haplo?
 int haploSize = hChromSize(database, haplotypeId); // hopefully this will work
-//warn("database=%s, haplotypeId=%s, haploSize=%d", database, haplotypeId, haploSize);  //  DEBUG REMOVE
 
 // insert into list replacing original haploChrom record
 struct virtRegion *before = NULL;
 boolean found = FALSE;
 long offset = 0;
 struct virtRegion *v;
 while ((v=slPopHead(&after)))
     {
     if (sameString(haploChrom, v->chrom))
 	{
 	found = TRUE;
 	break;
 	}
     offset += (v->end - v->start);
     slAddHead(&before, v);
@@ -3365,39 +3315,30 @@
 v->end   = chromSize;
 defaultVirtWinEnd += haploSize;
 if (defaultVirtWinEnd > chromSize)
     defaultVirtWinEnd = chromSize;
 slAddHead(&virtRegionList, v);
 
 slReverse(&virtRegionList);
 hFreeConn(&conn);
 
 defaultVirtWinStart += offset;
 defaultVirtWinEnd += offset;
 
 // concatenate the 3 lists.
 virtRegionList = slCat(before,slCat(virtRegionList,after));
 
-// DEBUG REMOVE testing
-//warn("initSingleAltHaplotype: offset=%ld", offset);
-//long testOffset = 0;
-//for (v=virtRegionList; v; v=v->next)
-//    {
-//    testOffset += (v->end - v->start);
-//    warn("%s:%d-%d cumuulative offset %ld", v->chrom, v->start, v->end, testOffset);
-//    }
-
 return TRUE;
 }
 
 
 void initVirtRegionsFromKnownCanonicalGenes(char *table)
 // OBSOLETED by initVirtRegionsFromEMGeneTableExons()
 /* Create a regionlist from knownCanonical genes (not exons) */
 // I was not expecting it, but 20% of the KC genes overlap with others.
 // Some are cDNAs, some are non-coding RNAs, some just look like junk.
 // But I have to add special logic to accomodate them.
 // Currently I just merge until there is no more overlap,
 // and then I start a new region. So 30K regions should reduce to about 24K regions or less.
 {
 struct sqlConnection *conn = hAllocConn(database);
 virtRegionList = NULL;
@@ -3566,31 +3507,30 @@
 int rowOffset = 0;
 char query[256];
 int padding = emPadding;
 if (sameString(virtModeType, "geneMostly"))
     padding = gmPadding;
 // knownCanonical Hash
 struct hash *kcHash = NULL;
 if (knownCanonical) // filter out alt splicing variants
     {
     // load up hash of canonical transcriptIds
     sqlSafef(query, sizeof(query), "select transcript from %s"
 	//" where chrom not like '%%_hap_%%' and chrom not like '%%_random'"
 	, knownCanonical);
     if (virtualSingleChrom())
 	sqlSafefAppend(query, sizeof(query), " where chrom='%s'", chromName);
-    //warn("query = [%s]", query); // DEBUG REMOVE
     kcHash = newHash(10);
     sr = sqlGetResult(conn, query);
     while ((row = sqlNextRow(sr)) != NULL)
 	{
 	hashAdd(kcHash, row[0], NULL);
 	}
     sqlFreeResult(&sr);
     }
 // knownToTag basic hash
 struct hash *ktHash = NULL;
 if (knownToTag) // filter out all but Basic
     {
     // load up hash of canonical transcriptIds
     sqlSafef(query, sizeof(query), "select name from %s where value='basic'", knownToTag);
     ktHash = newHash(10);
@@ -3601,31 +3541,30 @@
 	}
     sqlFreeResult(&sr);
     }
 setEMGeneTrack();
 if (!emGeneTable)
     errAbort("Unexpected error, emGeneTable=NULL in initVirtRegionsFromEMGeneTableExons");
 if (hIsBinned(database, emGeneTable)) // skip first bin column if any
     ++rowOffset;
 sqlSafef(query, sizeof(query), "select * from %s", emGeneTable);
 if (virtualSingleChrom())
     sqlSafefAppend(query, sizeof(query), " where chrom='%s'", chromName);
 // TODO GALT may have to change this to in-memory sorting?
 // refGene is out of order because of genbank continuous loading
 // also, using where chrom= causes it to use indexes which disturb order returned.
 sqlSafefAppend(query, sizeof(query), " order by chrom, txStart");  
-//warn("query = [%s]", query); // DEBUG REMOVE
 sr = sqlGetResult(conn, query);
 
 char chrom[256] = "";
 int start = -1;
 int end = -1;
 char lastChrom[256] = "";
 int lastStart = -1;
 int lastEnd = -1;
 int chromSize = -1;
 char lastChromSizeChrom[256] = "";
 boolean firstTime = TRUE;
 boolean isEOF = FALSE;
 struct kce *kceList = NULL, *bestKce, *prevKce;
 struct genePred *gene = NULL;
 while (1)
@@ -3633,250 +3572,231 @@
 
     while(1) // get input if possible
 	{
 	
 	boolean readIt = FALSE;
 	if (!gene)
 	    readIt = TRUE;
 	if (isEOF)
 	    readIt = FALSE;
 	if (readIt)
 	    {
 	    row = sqlNextRow(sr);
 	    if (row)
 		{
 		gene = genePredLoad(row+rowOffset);
-		//warn("GALT loaded gene %s\n", gene->name); // DEBUG REMOVE
 		if (geneMostly)
 		    convertGenePredGeneToExon(gene);
 		if (!sameString(lastChromSizeChrom, gene->chrom))
 		    {
 		    chromSize = hChromSize(database, gene->chrom);
 		    safecpy(lastChromSizeChrom, sizeof lastChromSizeChrom, gene->chrom);
 		    }
 		if (padding > 0)
 		    padExons(gene, chromSize, padding); // handle padding
 		}
 	    else
 		{
 		isEOF = TRUE;
 		}
 	    }
 	if (gene && !showNoncoding && (gene->cdsStart == gene->cdsEnd))
 	    {
-	    //warn("GALT skip non-coding gene %s cdsStart==cdsEnd", gene->name); // DEBUG REMOVE
+	    //skip non-coding gene
 	    genePredFree(&gene);
 	    }
 	if (gene && knownCanonical && !hashLookup(kcHash, gene->name))
 	    {
-	    //warn("GALT skip not in knownCanonical hash gene %s", gene->name); // DEBUG REMOVE
+	    //skip gene not in knownCanonical hash
 	    genePredFree(&gene);
 	    }
 	if (gene && knownToTag && !hashLookup(ktHash, gene->name))
 	    {
-	    //warn("GALT skip not in knownToTag Basic hash gene %s", gene->name); // DEBUG REMOVE
+	    // skip gene not in knownToTag Basic hash
 	    genePredFree(&gene);
 	    }
 	boolean transferIt = FALSE;
 	if (gene && !kceList)
 	    {
 	    transferIt = TRUE;
 	    }
 	else if (gene && kceList)
 	    {
 	    // TODO need to check the chrom equality first
 	    int best = findBestKce(kceList, &bestKce, &prevKce);
-	    //warn("GALT check chrom gene->chrom=%s, lastChrom=%s, chrom=%s", gene->chrom, lastChrom, chrom); // DEBUG REMOVE
 	    if (sameString(gene->chrom, chrom))
 		{
-		//warn("GALT best=%d gene %s exonStart[0]=%d", best, gene->name, gene->exonStarts[0]); // DEBUG REMOVE
 		if (gene->exonStarts[0] < best)
 		    transferIt = TRUE;
 		}
 	    }
 	if (transferIt)
 	    {
-	    //warn("GALT transferred gene %s to kcelist", gene->name); // DEBUG REMOVE
 	    // add gene to kce list
 	    struct kce *kce;
 	    AllocVar(kce);
 	    kce->gene = gene;
 	    kce->exonNumber = 0;
 	    slAddHead(&kceList, kce);
 	    safecpy(chrom, sizeof chrom, gene->chrom);
 	    gene = NULL; // do not free since it is still in use
 	    }
-	//warn("GALT readIt=%d transferIt=%d", readIt, transferIt); // DEBUG REMOVE
 	if (gene && kceList && !transferIt)
 	    break;
 	if (isEOF && !gene)
 	    {
 	    if (kceList) // flush out the last of the items in kcelist
 		findBestKce(kceList, &bestKce, &prevKce);
 	    break;
 	    }
 	}
 
 
     boolean printIt = FALSE;
 
     if (kceList)
 	{	    
 
 	safecpy(chrom, sizeof chrom, bestKce->gene->chrom);
 	start = bestKce->gene->exonStarts[bestKce->exonNumber];
 	end   = bestKce->gene->exonEnds[bestKce->exonNumber];
 
-	//warn("GALT GOT DATA chrom=%s start=%d end=%d lastChrom=%s lastStart=%d lastEnd=%d", 
-	    //chrom, start, end, lastChrom, lastStart, lastEnd); // DEBUG REMOVE
-
 	if (sameString(chrom, lastChrom))
 	    {
 	    if (start <= lastEnd)
 		{
-		//warn("GALT overlap extend start=%d <= lastEnd=%d, end=%d", start, lastEnd, end); // DEBUG REMOVE
-		// overlap detected in knownCanonical
-		// extend current region
+		// overlap detected, extend current region
 		if (end > lastEnd)
 		    {
 		    lastEnd = end;
 		    }
 		}
 	    else
 		{
 		printIt = TRUE;
 		}
 	    }
 	else
 	    {
 	    printIt = TRUE;
 	    }
 	}
     else
 	{
 	printIt = TRUE;
 	isEOF = TRUE;
 	}
 
-    //warn("GALT printIt=%d", printIt); // DEBUG REMOVE
-
     if (printIt)
 	{
 	if (firstTime)
 	    {
 	    firstTime = FALSE;
 	    }
 	else
 	    {
-	    //warn("GALT adding region %s:%d-%d", lastChrom, lastStart, lastEnd); // DEBUG REMOVE
 	    struct virtRegion *v;
 	    AllocVar(v);
 	    v->chrom = cloneString(lastChrom);
 	    v->start = lastStart;
 	    v->end   = lastEnd;
 	    v->strand[0] = '.';  // TODO we should probably just remove the strand field
 	    v->strand[1] = 0;
 	    slAddHead(&virtRegionList, v);
 	    
 	    }
 	}
 
     if (isEOF && !kceList && !gene)
 	break;
 
     if (printIt)
 	{
 	safecpy(lastChrom, sizeof lastChrom, chrom);
 	lastStart = start;
 	lastEnd = end;
 	}
 
-    //warn("used up  %s exon# %d", bestKce->gene->name, bestKce->exonNumber);  // DEBUG REMOVE
-    // TODO update or remove current thing from kceList
     ++bestKce->exonNumber;
     if (bestKce->exonNumber >= bestKce->gene->exonCount)
 	{  // remove from kceList
 	genePredFree(&bestKce->gene);
 	if (prevKce)
 	    prevKce->next = bestKce->next;
 	else
 	    kceList = bestKce->next;
 	freeMem(bestKce);
 	}
     
     }
 sqlFreeResult(&sr);
 slReverse(&virtRegionList);
 hashFree(&kcHash);
 hashFree(&ktHash);
 hFreeConn(&conn);
 }
 
 
 void testRegionList()
 /* check if it is ascending non-overlapping regions. 
 (this is not always a requirement in the most general case, i.e. user-regions)
 */
 {
 char lastChrom[256];
 int lastEnd = -1;
 struct virtRegion *v;
-warn("testRegionList() started DEBUG."); // DEBUG REMOVE
 for (v=virtRegionList; v; v=v->next)
     {
     if (sameString(v->chrom,lastChrom))
 	{
 	if (v->end < v->start)
 	    errAbort("check of region list reveals invalid region %s:%d-%d", v->chrom, v->start, v->end);
 	if (lastEnd > v->start)
 	    errAbort("check of region list reveals overlapping regions region %s:%d-%d lastEnd=%d",  v->chrom, v->start, v->end, lastEnd);
 	}
     else
 	{
 	safecpy(lastChrom, sizeof lastChrom, v->chrom);
 	}
     lastEnd = v->end;
     }
-warn("testRegionList() completed OK.");
 }
 
 
 // multi-window variables global to hgTracks
 
 
 void setGlobalsFromWindow(struct window *window)
 /* set global window values */
 {
 currentWindow = window;
 organism  = window->organism;
 database  = window->database;
 chromName = window->chromName;
 winStart  = window->winStart;
 winEnd    = window->winEnd;
 insideX   = window->insideX;
 insideWidth = window->insideWidth;
 winBaseCount = winEnd - winStart;
 }
 
 
 void initExonStep()
 /* create exon-like pattern with exonSize and stepSize */
 {
 int winCount = cartUsualInt(cart, "demo2NumWindows", demo2NumWindows);
 int i;
-//int avgWidth = fullInsideWidth/winCount ; // can shrink down to 1 ok! // DEBUG REMOVE
-//int x = fullInsideX;
 int exonSize = cartUsualInt(cart, "demo2WindowSize", demo2WindowSize);  //200; //9974; //200;
 int intronSize = cartUsualInt(cart, "demo2StepSize", demo2StepSize); //200; //15000; // really using it like stepSize as that allows overlapping windows.
 struct virtRegion *v;
 for(i=0;i<winCount;++i)
     {
     AllocVar(v);
     //chr21:33,031,597-33,041,570
     v->chrom = "chr21";
     v->start = 33031597 - 1 + i*(intronSize);
     v->end = v->start + exonSize; //33041570;
     slAddHead(&virtRegionList, v);
     }
 slReverse(&virtRegionList);
 //if (winCount >= 2)
 //    withNextExonArrows = FALSE;	/* Display next exon navigation buttons near center labels? */
@@ -3892,39 +3812,36 @@
 int winCount = 0;
 char *query =
 "NOSQLINJ select chrom, size from chromInfo"
 " where chrom     like 'chr%'"
 " and   chrom not like '%_random'"
 " and   chrom not like 'chrUn%'";
 // allow alternate haplotypes for now
 //" and   chrom not like '%_hap%'"
 //" and   chrom not like '%_alt'"
 //warn("%s",query);
 struct virtRegion *v;
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     unsigned chromSize = sqlUnsigned(row[1]);
-    //warn("chrom=%s size=%d", row[0], chromSize); 
     AllocVar(v);
     v->chrom = cloneString(row[0]);
     v->start = 1 - 1;
     v->end   = chromSize;
     slAddHead(&virtRegionList, v);
     ++winCount;
-    //if (winCount >= 2)  // DEBUG HACK REMOVE
-	//break;  
     }
 sqlFreeResult(&sr);
 hFreeConn(&conn);
 slReverse(&virtRegionList);
 }
 
 
 
 void initWindowsAltLoci()
 /* initialize window list showing alt (alternate haplotype)*/
 {
 
 struct virtRegion *v;
 //chr1:153520530-153700530
 AllocVar(v);
@@ -3945,150 +3862,135 @@
 AllocVar(v);
 v->chrom = "chr1";
 v->start = 153865739 - 1;
 v->end   = 154045739;
 slAddHead(&virtRegionList, v);
 
 slReverse(&virtRegionList);
 
 }
 
 boolean initVirtRegionsFromBedUrl(time_t *bedDateTime)
 /* Read custom regions from BED URL */
 {
 multiRegionsBedUrl = cartUsualString(cart, "multiRegionsBedUrl", multiRegionsBedUrl);
 int bedPadding = 0; // default no padding
-//warn("initVirtRegionsFromBedUrl got here multiRegionsBedUrl=%s", multiRegionsBedUrl); // DEBUG REMOVE
 // TODO add some checks for db change? save in cart var?
 if (sameString(multiRegionsBedUrl,""))
     {
     warn("No BED URL specified.");
     return FALSE;
     }
 if (!strstr(multiRegionsBedUrl,"://"))
     {
     warn("No protocol specified in BED URL %s", multiRegionsBedUrl);
     return FALSE;
     }
 struct lineFile *lf = lineFileUdcMayOpen(multiRegionsBedUrl, FALSE);
 if (!lf)
     {
     warn("Unable to open [%s] with udc", multiRegionsBedUrl);
     return FALSE;
     }
 *bedDateTime = udcTimeFromCache(multiRegionsBedUrl, NULL);
-//warn("unix time = %ld on BED file %s", (long)*bedDateTime, multiRegionsBedUrl); // DEBUG REMOVE
 char *line;
 int lineSize;
 int expectedFieldCount = -1;
 struct bed *bed, *bedList = NULL;
 while (lineFileNext(lf, &line, &lineSize))
     {
     // Process comments for keywords like database, shortDesc, and maybe others
     if (startsWith("#",line))
 	{
 	if (startsWith("#database ",line))
 	    {
 	    char *dbFromBed = line+strlen("#database ");
-	    //warn("got #database setting: %s,  current database %s", dbFromBed, database); // DEBUG REMOVE
 	    if (!sameString(database,dbFromBed))
 		{
 		warn("Multi-Region BED URL error: The database (%s) specified in input does not match current database %s", 
 		   dbFromBed, database);
 		return FALSE;
 		}
 	    }
 	if (startsWith("#shortDesc ",line))
 	    {
 	    virtModeShortDescr = cloneString(line+strlen("#shortDesc "));
-	    //warn("got #shortDesc setting: %s", virtModeShortDescr); // DEBUG REMOVE
 	    }
 	if (startsWith("#padding ",line))
 	    {
 	    bedPadding = sqlSigned(line+strlen("#padding "));
-	    //warn("got #padding setting: %d", bedPadding); // DEBUG REMOVE
 	    }
 	continue;
 	}
 
     char *row[15];
     int numFields = chopByWhite(line, row, ArraySize(row));
     if (numFields < 3)
 	{
         warn("%s doesn't appear to be in BED format. 3 or more fields required, got %d",
                 multiRegionsBedUrl, numFields);
 	return FALSE;
 	}
     if (expectedFieldCount == -1)
 	{
 	expectedFieldCount = numFields;
-	//warn("got expectedFieldCount=%d", expectedFieldCount); // DEBUG REMOVE
 	}
     else
 	{
-	//warn("got numFields=%d, expectedFieldCount=%d", numFields, expectedFieldCount); // DEBUG REMOVE
 	if (numFields != expectedFieldCount)
 	    errAbort("Multi-Region BED was detected to have %d columns. But this row has %d columns. "
 	    "All rows except comment lines should have the same number of columns", numFields, expectedFieldCount);
 	}
 
-    //warn("got about to call load and validate bed"); // DEBUG REMOVE
-
     AllocVar(bed);
     // All fields are standard BED fields, no bedplus fields supported at this time.
     // note: this function does not validate chrom name or end beyond chrom size
     loadAndValidateBed(row, numFields, numFields+0, lf, bed, NULL, TRUE);
     bed->chrom=cloneString(bed->chrom);  // loadAndValidateBed does not do it for speed. but bedFree needs it.
 
     struct chromInfo *ci = hGetChromInfo(database, bed->chrom);
     if (ci == NULL)
 	{
         warn("Couldn't find chromosome/scaffold %s in database", bed->chrom);
 	return FALSE;
 	}
     if (bed->chromEnd > ci->size)
 	{
         warn("BED chromEnd %u > size %u for chromosome/scaffold %s", bed->chromEnd, ci->size, bed->chrom);
 	return FALSE;
 	}
 
     slAddHead(&bedList, bed);
 
-    //warn("got after load and validate bed"); // DEBUG REMOVE
-
     struct virtRegion *v;
     if (numFields < 12)
 	{
 	AllocVar(v);
 	v->chrom = cloneString(bed->chrom);
 	v->start = bed->chromStart;
 	v->end   = bed->chromEnd;
 	slAddHead(&virtRegionList, v);
-	//warn("got BED region %s %d %d", v->chrom, v->start, v->end); // DEBUG REMOVE
 	}
     else
 	{
 	int e;
-	//warn("got BED12 blockCount=%d bed->chrom=%s", bed->blockCount, bed->chrom); // DEBUG REMOVE
 	for (e = 0; e < bed->blockCount; ++e)
 	    {
-	    //warn("got BED12 exon blockSizes[e]=%d chromStarts[e]=%d", bed->blockSizes[e], bed->chromStarts[e]); // DEBUG REMOVE
 	    AllocVar(v);
 	    v->chrom = cloneString(bed->chrom);
 	    v->start = bed->chromStart + bed->chromStarts[e];
 	    v->end   = v->start + bed->blockSizes[e];
-	    //warn("got BED12 exon region %s %d %d", v->chrom, v->start, v->end); // DEBUG REMOVE
 	    slAddHead(&virtRegionList, v);
 	    }
 	}
 
     }
 lineFileClose(&lf);
 bedFreeList(&bedList);
 slReverse(&virtRegionList);
 if (bedPadding > 0)
     padVirtRegions(bedPadding);
 return TRUE;
 }
 
 // TODO OBSOLETED by lastDbPosCart
 boolean restoreCartSetting(char *cartSetting)
@@ -4142,71 +4044,61 @@
 
 void dySaveCartSetting(struct dyString *dy, char *cartVar, boolean saveBoth)
 /* Grab var and value from cart, save as var=val to dy string. */
 {
 if (dy->stringSize > 0)
     dyStringAppend(dy, " ");
 dyStringPrintf(dy, "%s=%s", cartVar, cartUsualString(cart, cartVar, NULL));
 if (saveBoth)
     lastDbPosSaveCartSetting(cartVar);
 }
 
 
 boolean initRegionList()
 /* initialize window list */
 {
-//warn("initRegionList got here 0"); 
 
 // TODO GALT
-// if we are going to support windows from any org and db,
-// then we are going to have to loosen up assumptions
-// about trackList consistencey across windows.
-// But it seems like much of the rest of the code would work.
-// Not sure about speed either -- but might be ok.
-//
 //  update, well by 2015-04-28 it seems like we are not going to support windows from other assemblies
 // due to difficulties with tracklist.
 
-
 struct virtRegion *v;
 virtRegionList = NULL;
 virtModeExtraState = "";   // This is state that determines if the virtChrom has changed
 lastDbPosCart = cartOfNothing();  // USED to store and restore cart settings related to position and virtMode
 struct dyString *dy = dyStringNew(256);  // used to build virtModeExtraState
 
 if (sameString(virtModeType, "default"))
     { 
-    //warn("demo type single original window"); // DEBUG REMOVE
     // Single window same as normal window
     // mostly good to test nothing was broken with single window
     AllocVar(v);
 
     v->chrom = chromName;
     v->start = 0;
     v->end = hChromSize(database, chromName);
 
     virtWinStart = winStart;
     virtWinEnd   = winEnd;
 
     slAddHead(&virtRegionList, v);
     slReverse(&virtRegionList);
     }
 else if (sameString(virtModeType, "exonMostly")
       || sameString(virtModeType, "geneMostly"))
     {
 
-    //warn("emGeneTable %s", emGeneTable); // DEBUG REMOVE
     // Gencode settings: comprehensive, alt-splice, non-coding
 
     char *knownCanonical = NULL;  // show splice-variants, not filtered out via knownCanonical
     boolean showNoncoding = TRUE; // show non-coding where cdsStart==cdsEnd
     char *knownToTag = NULL;      // show comprehensive set not filtered by knownToTag
     char varName[SMALLBUF];
     boolean geneMostly = FALSE;
 
     lastDbPosSaveCartSetting("emGeneTable");
 
     //DISGUISE makes obsolete dySaveCartSetting(dy, "emGeneTable");
     //DISGUISE makes obsolete dySaveCartSetting(dy, "emPadding");
     if (sameString(virtModeType, "geneMostly"))
 	geneMostly = TRUE;
     if (sameString(emGeneTable, "knownGene"))
@@ -4238,273 +4130,244 @@
 		{
 		knownToTag = "knownToTag";
 		}
 	    }
 
 	}
     if (sameString(emGeneTable, "refGene"))
 	{
 	char varName[SMALLBUF];
 	safef(varName, sizeof(varName), "%s.hideNoncoding", emGeneTable);
 	showNoncoding = !cartUsualBoolean(cart, varName, FALSE);
 	//DISGUISE makes obsolete dySaveCartSetting(dy, varName);
 	}
 
     initVirtRegionsFromEMGeneTableExons(showNoncoding, knownCanonical, knownToTag, geneMostly);
-    //warn("slCount(virtRegionList)=%d", slCount(virtRegionList));  // DEBUG REMOVE
     if (!virtRegionList)
 	{
 	warn("No genes found on chrom %s for track %s, returning to default view", chromName, emGeneTrack->shortLabel);
 	return FALSE;   // regionList is empty, nothing found.
 	}
     if (geneMostly)
 	virtModeShortDescr = "genes";
     else
 	virtModeShortDescr = "exons";
     // DISGUISE makes obsolete dyStringPrintf(dy," %s %s", dy->string, knownCanonical, knownToTag);
     }
 else if (sameString(virtModeType, "kcGenes")) // TODO obsolete
     {
-    //warn("demo KnownCanonical gene regions genome-wide."); // DEBUG REMOVE
     initVirtRegionsFromKnownCanonicalGenes("knownCanonical"); 
     virtModeShortDescr = "genes";
     }
 else if (sameString(virtModeType, "customUrl"))
     {
-    //warn("custom regions from BED URL."); // DEBUG REMOVE
+    // custom regions from BED URL
     virtModeShortDescr = "customUrl";  // can be overridden by comment in input bed file
     time_t bedDateTime = 0;
     if (!initVirtRegionsFromBedUrl(&bedDateTime))
 	{
 	return FALSE; // return to default mode
 	}
     dySaveCartSetting(dy, "multiRegionsBedUrl", TRUE);
     dyStringPrintf(dy, " %ld", (long)bedDateTime);
     }
 else if (sameString(virtModeType, "singleTrans"))
     {
-    //warn("Single Transcript Id"); // DEBUG REMOVE
     singleTransId = cartUsualString(cart, "singleTransId", singleTransId); 
     if (sameString(singleTransId, ""))
 	{
 	warn("Single transcript Id should not be blank");
 	return FALSE; // return to default mode
 	}
     setEMGeneTrack();
     dySaveCartSetting(dy, "singleTransId", TRUE);
     }
 else if (sameString(virtModeType, "singleAltHaplo"))
     {
-    //warn("Single Haplotype Id"); // DEBUG REMOVE
-    singleAltHaploId = cartUsualString(cart, "singleAltHaploId", singleAltHaploId); // currently default is chr6_cox_hap2
+    singleAltHaploId = cartUsualString(cart, "singleAltHaploId", singleAltHaploId); // default is chr6_cox_hap2
     initAllChroms();  // we want to default to full genome view.
     if (!initSingleAltHaplotype(singleAltHaploId))
 	{
 	virtRegionList = NULL;
 	return FALSE; // return to default mode
 	}
     virtModeShortDescr = "alt haplo";  // was "single haplo" but that might confuse some users.
     dySaveCartSetting(dy, "singleAltHaploId", TRUE);
     }
 else if (sameString(virtModeType, "allChroms"))
-    {
+    { // TODO more work on this mode
     //warn("show all regular chromosomes (not alts)\n"
-	//"Warning must turn off all tracks except big*"); // DEBUG REMOVE
+	//"Warning must turn off all tracks except big*");
     initAllChroms();
     }
 else if (sameString(virtModeType, "demo1"))
     {
-    //warn("demo two windows on two chroms (default posn chr21, and same loc on chr22"); // DEBUG REMOVE
-
-    // NOTE we are losing the ability to specify org and db
+    // demo two windows on two chroms (default posn chr21, and same loc on chr22
 
     //chr21:33,031,597-33,041,570
     AllocVar(v);
     //chr21:33,031,597-33,041,570
     v->chrom = "chr21";
     v->start = 33031597 - 1;
     v->end = 33041570;
     slAddHead(&virtRegionList, v);
 
     struct virtRegion *v2;
 
     AllocVar(v2);
     //chr22:33,031,597-33,041,570
     //window2->organism  = "Mouse";
     //window2->database  = "mm10";
     //window2->database  = "hg38";
     v2->chrom = "chr22";
     v2->start = 33031597 - 1;
     v2->end = 33041570;
     slAddHead(&virtRegionList, v2);
 
     slReverse(&virtRegionList);
     }
 else if (sameString(virtModeType, "demo2"))
     {
-    //warn("demo multiple (70) windows on one chrom chr21 def posn, window size and step exon-like"); // DEBUG REMOVE
+    // demo multiple (70) windows on one chrom chr21 def posn, window size and step exon-like
     initExonStep();
     }
 else if (sameString(virtModeType, "demo4"))
     {
-    //warn("demo multiple (20) windows showing exons from TITIN gene uc031rqd.1."); // DEBUG REMOVE
+    // demo multiple (20) windows showing exons from TITIN gene uc031rqd.1.
     initVirtRegionsFromEmGeneTable("uc031rqd.1"); // TITIN // "uc002ypa.3"); // SOD1
     }
 else if (sameString(virtModeType, "demo5"))
     {
-    //warn("demo alt locus on hg38\n"
-	//"Shows alt chrom surrounded by preceding and following regions of same size from reference genome "); // DEBUG REMOVE
+    // demo alt locus on hg38
+    //  Shows alt chrom surrounded by preceding and following regions of same size from reference genome.
     initWindowsAltLoci();
     }
 else if (sameString(virtModeType, "demo6"))
     {
-    //warn("demo SOD1\n"
-	//"Shows zoomed in exon-exon junction from SOD1 gene, between exon1 and exon2."); // DEBUG REMOVE
+    // demo SOD1
+    //  Shows zoomed in exon-exon junction from SOD1 gene, between exon1 and exon2.
 
     initVirtRegionsFromSOD1Hardwired();
 
     }
 else
     {
-    //warn("unrecognized virtModeType = %s", virtModeType);
+    // Unrecognized virtModeType
     return FALSE; // return to default mode
     }
 
 virtModeExtraState = dyStringCannibalize(&dy);
 
 if (!virtRegionList)
     return FALSE;   // regionList is empty, nothing found.
 
 return TRUE;
 
 }
 
 boolean isLimitedVisHiddenForAllWindows(struct track *track)
 /* Check if track limitedVis == hidden for all windows. 
  * Return true if all are hidden */
 {
 boolean result = TRUE;
 for(;track;track=track->nextWindow)
     if (track->limitedVis != tvHide)
 	result = FALSE;
 return result;
 }
 
 boolean isTypeBedLike(struct track *track)
 /* Check if track type is BED-like packable thing (but not rmsk or joinedRmsk) */
 { // TODO GALT do we have all the types needed?
 // TODO could it be as simple as whether track->items exists?
 char *typeLine = track->tdb->type, *words[8], *type;
 int wordCount;
-//warn("track %s has type %s", track->track, typeLine); 
 if (typeLine == NULL)
     return FALSE;
 wordCount = chopLine(cloneString(typeLine), words);
 if (wordCount <= 0)
     return FALSE;
 type = words[0];
-//warn("track %s has type word[0] = %s, canPack=%d", track->track, type, track->canPack); 
 if (
 (  sameWord(type, "bed")
 || sameWord(type, "bed5FloatScore")
 || sameWord(type, "bed6FloatScore")
 || sameWord(type, "bedDetail")
 || sameWord(type, "bigBed")
 || sameWord(type, "bigGenePred")
 || sameWord(type, "broadPeak")
 || sameWord(type, "chain")
 || sameWord(type, "factorSource")
 || sameWord(type, "genePred")
 || sameWord(type, "gvf")
 || sameWord(type, "narrowPeak")
 || sameWord(type, "psl")
 //|| track->loadItems == loadSimpleBed
 //|| track->bedSize >= 3 // should pick up several ENCODE BED-Plus types.
 ) 
 && track->canPack
    )
     {
-    //warn("track %s is BEDLIKE", track->track); 
     return TRUE;
     }
 
-//warn("track %s is NOT BEDLIKE", track->track); 
 return FALSE;
 }
 
 boolean isTypeUseItemNameAsKey(struct track *track)
 /* Check if track type is like expRatio and key is just item name. */
 { 
-
 char *typeLine = track->tdb->type, *words[8], *type;
 int wordCount;
-//warn("track %s has type %s", track->track, typeLine); 
 if (typeLine == NULL)
     return FALSE;
 wordCount = chopLine(cloneString(typeLine), words);
 if (wordCount <= 0)
     return FALSE;
 type = words[0];
-//warn("track %s has type word[0] = %s", track->track, type); 
 if (sameWord(type, "expRatio"))
     {
-    //warn("track %s is like expRatio, needs one row per item", track->track); 
+    // track is like expRatio, needs one row per item
     return TRUE;
     }
-
-//warn("track %s is NOT like expRatio, which needs only one row per item", track->track); 
 return FALSE;
 }
 
 void setFlatTrackMaxHeight(struct flatTracks *flatTrack, int fontHeight)
 /* for each flatTrack, figure out maximum height needed from all windows */
 {
 struct track *track = flatTrack->track;
 int maxHeight = 0;
 struct track *winTrack;
 struct window *window;
 for (window=windows, winTrack=track; window; window=window->next, winTrack=winTrack->nextWindow)
     {
     setGlobalsFromWindow(window);
 
     int trackHeight =  trackPlusLabelHeight(winTrack, fontHeight);
 
-    //warn("track %s height=%d isCenterLabelIncluded(winTrack)=%d\n", winTrack->track, trackHeight, isCenterLabelIncluded(winTrack)); // DEBUG REMOVE
-    //fflush(stdout); // DEBUG REMOVE
-
     if (trackHeight > maxHeight)
 	maxHeight = trackHeight;
     }
 setGlobalsFromWindow(windows); // first window
 
 flatTrack->maxHeight = maxHeight;
-
-//warn("track %s maxHeight=%d\n", track->track, maxHeight); // DEBUG REMOVE
-//fflush(stdout); // DEBUG REMOVE
 }
 
 void makeActiveImage(struct track *trackList, char *psOutput)
 /* Make image and image map. */
 {
-
-boolean galtDebug = FALSE;
-
-if (galtDebug)
-warn("makeActiveImage begins");
-
-struct window *window = NULL;
-
 struct track *track;
 MgFont *font = tl.font;
 struct hvGfx *hvg;
 struct tempName pngTn;
 char *mapName = "map";
 int fontHeight = mgFontLineHeight(font);
 int trackPastTabX = (withLeftLabels ? trackTabWidth : 0);
 int trackTabX = gfxBorder;
 int trackPastTabWidth = tl.picWidth - trackPastTabX;
 int pixWidth, pixHeight;
 int y=0;
 int titleHeight = fontHeight;
 int scaleBarPad = 2;
 int scaleBarHeight = fontHeight;
 int scaleBarTotalHeight = fontHeight + 2 * scaleBarPad;
@@ -4528,32 +4391,30 @@
 leftLabelWidth = insideX - gfxBorder*3;
 
 struct image *theOneImg  = NULL; // No need to be global, only the map needs to be global
 struct image *theSideImg = NULL; // Because dragScroll drags off end of image,
                                  //    the side label gets seen. Therefore we need 2 images!!
 //struct imgTrack *curImgTrack = NULL; // Make this global for now to avoid huge rewrite
 struct imgSlice *curSlice    = NULL; // No need to be global, only the map needs to be global
 //struct mapSet   *curMap      = NULL; // Make this global for now to avoid huge rewrite
 // Set up imgBox dimensions
 int sliceWidth[stMaxSliceTypes]; // Just being explicit
 int sliceOffsetX[stMaxSliceTypes];
 int sliceHeight        = 0;
 int sliceOffsetY       = 0;
 char *rulerTtl = NULL;
 
-//warn("theImgBox=%lu", (unsigned long)theImgBox); // DEBUG REMOVE
-
 if (theImgBox)
 // if theImgBox == NULL then we are rendering a simple single image such as right-click View image.
 // theImgBox is a global for now to avoid huge rewrite of hgTracks.  It is started
 // prior to this in doTrackForm()
     {
     rulerTtl = "drag select or click to zoom";
     hPrintf("<input type='hidden' name='db' value='%s'>\n", database);
     hPrintf("<input type='hidden' name='c' value='%s'>\n", chromName);
     hPrintf("<input type='hidden' name='l' value='%d'>\n", winStart);
     hPrintf("<input type='hidden' name='r' value='%d'>\n", winEnd);
     hPrintf("<input type='hidden' name='pix' value='%d'>\n", tl.picWidth);
     // If a portal was established, then set the global dimensions to the entire expanded image size
     if (imgBoxPortalDimensions(theImgBox,&virtWinStart,&virtWinEnd,&(tl.picWidth),NULL,NULL,NULL,NULL,NULL))
         {
         pixWidth = tl.picWidth;
@@ -4617,192 +4478,164 @@
     yAfterBases = yAfterRuler;
     pixHeight += basePositionHeight;
     if (rulerCds)
         {
         yAfterRuler += rulerTranslationHeight;
         pixHeight += rulerTranslationHeight;
         }
     }
 
 
 /* Hash tracks/subtracks, limit visibility and calculate total image height: */
 
 // For multiple windows, sets height and visibility
 //       as well as making the flatTrack list.
 
-if (galtDebug)
-warn("organism=%s database=%s", organism, database); // DEBUG REMOVE
-
 // TODO there is a chance that for pack and squish
 // I might need to trigger a track-height check here
 // since it is after all items are loaded for all windows
 // but before things are checked for overflow or limitedVis?
 // The fixed non-overflow tracks like knownGene used to initialize 
 // ss and track height during loadItems(). That was delayed
 // because we now need all windows to be fully loaded before
 // calculating their joint ss layout and height.
 
 // set heights and visibilities.
-if (galtDebug)
-warn("set heights and visibilities"); // DEBUG REMOVE
+struct window *window = NULL;
 for(window=windows;window;window=window->next)
     {
-    //warn("**** window=%lu insideX=%d insideWidth=%d", (unsigned long) window, window->insideX, window->insideWidth); // DEBUG REMOVE
     setGlobalsFromWindow(window);
     trackList = window->trackList;
     for (track = trackList; track != NULL; track = track->next)
 	{
 	if (tdbIsCompositeChild(track->tdb)) // When single track is requested via AJAX,
 	    limitedVisFromComposite(track);  // it could be a subtrack
 	else
 	    {
-	    //warn("DEBUG REMOVE regular track %s", track->track);  // DEBUG REMOVE
 	    limitVisibility(track);
 	    }
 
 	if (tdbIsComposite(track->tdb))
 	    {
 	    struct track *subtrack;
 	    for (subtrack = track->subtracks; subtrack != NULL; subtrack = subtrack->next)
 		{
 		if (!isSubtrackVisible(subtrack))
 		    continue;
 
 		// subtrack vis can be explicit or inherited from composite/view.
 		// Then it could be limited because of pixel height
 		limitedVisFromComposite(subtrack);
 
 		if (subtrack->limitedVis != tvHide)
 		    {
 		    subtrack->hasUi = track->hasUi;
 		    }
 		}
 	    }
-
-	//warn("heights and vis: track %s vis=%d limitedVis==%d limitedVisSet=%d", track->track, track->visibility, track->limitedVis, track->limitedVisSet); // DEBUG REMOVE
 	}
     }
 trackList = windows->trackList;
 setGlobalsFromWindow(windows); // first window
 
 // Construct flatTracks 
-if (galtDebug)
-warn("Construct flatTracks");
 for (track = trackList; track != NULL; track = track->next)
     {
-    //warn("construct flat track %s vis=%d limitedVis==%d", track->track, track->visibility, track->limitedVis); // DEBUG REMOVE
     if (tdbIsComposite(track->tdb))
         {
         struct track *subtrack;
         for (subtrack = track->subtracks; subtrack != NULL; subtrack = subtrack->next)
             {
             if (!isSubtrackVisible(subtrack))
                 continue;
 
-	    //warn("about to call isLimitedVisHiddenForAllWindows(%s) on subtrack", subtrack->track);
 	    if (!isLimitedVisHiddenForAllWindows(subtrack))
                 {
-		//warn("adding flatTrack subtrack (%s)", subtrack->track); // DEBUG REMOVE
                 flatTracksAdd(&flatTracks,subtrack,cart);
                 }
             }
         }
     else
 	{	
-	//warn("about to call isLimitedVisHiddenForAllWindows(%s) on track", track->track);// DEBUG REMOVE
 	if (!isLimitedVisHiddenForAllWindows(track))
 	    {
-	    //warn("adding flatTrack track (%s)", track->track); // DEBUG REMOVE
 	    flatTracksAdd(&flatTracks,track,cart);
 	    }
 	}
     }
-//warn("slCount(flatTracks)=%d", slCount(flatTracks)); // DEBUG REMOVE
 flatTracksSort(&flatTracks); // Now we should have a perfectly good flat track list!
 
 
 // for each track, figure out maximum height needed from all windows
-if (galtDebug)
-warn("for each track, figure out maximum height needed from all windows");
 for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
     {
     track = flatTrack->track;
 
     if (track->limitedVis == tvHide)
 	{
-	//warn("flat track %s limitedVis==tvHide. why?", track->track); // DEBUG REMOVE
 	continue;
 	}
 
     setFlatTrackMaxHeight(flatTrack, fontHeight);
     
     }
 
-//warn("got done with flatTrack->maxHeight");
-
 
 // fill out track->prevTrack, and check for maxSafeHeight
-if (galtDebug)
-warn("fill out track->prevTrack, and check for maxSafeHeight");
 boolean safeHeight = TRUE;
 /* firefox on Linux worked almost up to 34,000 at the default 620 width */
 #define maxSafeHeight   32000
 struct track *prevTrack = NULL;
 for (flatTrack = flatTracks,prevTrack=NULL; flatTrack != NULL; flatTrack = flatTrack->next)
     {
     track = flatTrack->track;
     assert(track->limitedVis != tvHide);
     // ORIG int totalHeight = pixHeight+trackPlusLabelHeight(track,fontHeight);
-    //warn("track %s flat maxHeight=%d", track->track, flatTrack->maxHeight); // DEBUG REMOVE
     int totalHeight = pixHeight+flatTrack->maxHeight;
     if (totalHeight > maxSafeHeight)
         {
         char numBuf[SMALLBUF];
         sprintLongWithCommas(numBuf, maxSafeHeight);
         if (safeHeight)  // Only one message
             warn("Image is over %s pixels high (%d pix) at the following track which is now "
                  "hidden:<BR>\"%s\".%s", numBuf, totalHeight, track->tdb->longLabel,
                  (flatTrack->next != NULL ?
                       "<BR>Additional tracks may have also been hidden at this zoom level." : ""));
         safeHeight = FALSE;
 	struct track *winTrack;
 	for(winTrack=track;winTrack;winTrack=winTrack->nextWindow)
 	    {
 	    track->limitedVis = tvHide;
 	    track->limitedVisSet = TRUE;
 	    }
         }
     if (!isLimitedVisHiddenForAllWindows(track))
         {
-	//warn("setting winTracks ->prevTrack to %lu for all windows", (unsigned long) prevTrack);  // DEBUG REMOVE
 	struct track *winTrack;
 	for(winTrack=track;winTrack;winTrack=winTrack->nextWindow)
 	    { // TODO this is currently still only using one prev track value.
 	    winTrack->prevTrack = prevTrack; // Important for keeping track of conditional center labels!
 	    }
         // ORIG pixHeight += trackPlusLabelHeight(track, fontHeight);
 	if (!theImgBox) // prevTrack may have altered the height, so recalc height
 	    setFlatTrackMaxHeight(flatTrack, fontHeight);
 	pixHeight += flatTrack->maxHeight;
         prevTrack = track;
         }
     }
 
-if (galtDebug)
-warn("About to allocate hvg png pixWidth=%d, pixHeight=%d", pixWidth, pixHeight);
-fflush(stdout); // DEBUG REMOVE
-
+// allocate hvg png of pixWidth, pixHeight
 imagePixelHeight = pixHeight;
 if (psOutput)
     {
     hvg = hvGfxOpenPostScript(pixWidth, pixHeight, psOutput);
     hvgSide = hvg; // Always only one image
     }
 else
     {
     boolean transparentImage = FALSE;
     if (theImgBox!=NULL)
         transparentImage = TRUE;   // transparent because BG (blue ruler lines) is separate image
 
     if (measureTiming)
         measureTime("Time at start of obtaining trash hgt png image file");
     trashDirFile(&pngTn, "hgt", "hgt", ".png");
@@ -4849,57 +4682,50 @@
 
 // Good to go ahead and add all imgTracks regardless of buttons, left label, centerLabel, etc.
 if (theImgBox)
     {
     if (rulerMode != tvHide)
         {
         curImgTrack = imgBoxTrackFindOrAdd(theImgBox,NULL,RULER_TRACK_NAME,rulerMode,FALSE,
                                            IMG_FIXEDPOS); // No tdb, no centerLbl, not reorderable
         }
 
     for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
         {
         track = flatTrack->track;
 	if (!isLimitedVisHiddenForAllWindows(track))
             {
-	    //warn("hvGfxFindRgb !isLimitedVisHiddenForAllWindows(%s)", track->track);  // DEBUG REMOVE
 	    struct track *winTrack;
 	    for (winTrack=track; winTrack; winTrack=winTrack->nextWindow)
 		{
-		//warn("hvGfxFindRgb (%s) winTrack labelColor=%d ixColor=%d color=%s", track->track, winTrack->labelColor, winTrack->ixColor, rgbColorToString(winTrack->color));  // DEBUG REMOVE
 		if (winTrack->labelColor == winTrack->ixColor && winTrack->ixColor == 0)
 		    {
-		    //warn("hvGfxFindRgb got here window : %s %s %s:%d-%d offset %d width %d", // DEBUG REMOVE
-			  //window->organism, window->database, window->chromName, window->winStart+1, window->winEnd, window->insideX, window->insideWidth);
-
 		    winTrack->ixColor = hvGfxFindRgb(hvg, &winTrack->color);
-
 		    }
 		}
             int order = flatTrack->order;
             curImgTrack = imgBoxTrackFindOrAdd(theImgBox,track->tdb,NULL,track->limitedVis,
                                                isCenterLabelIncluded(track),order);
             if (trackShouldUseAjaxRetrieval(track))
                 imgTrackMarkForAjaxRetrieval(curImgTrack,TRUE);
             }
         }
     }
 
 
 /* Draw mini-buttons. */
-if (galtDebug)
-warn("Draw mini-buttons.");
+
 if (withLeftLabels && psOutput == NULL)
     {
     int butOff;
     boolean grayButtonGroup = FALSE;
     struct group *lastGroup = NULL;
     y = gfxBorder;
     if (rulerMode != tvHide)
         {
         /* draw button for Base Position pseudo-track */
         int height = basePositionHeight;
         if (rulerCds)
             height += rulerTranslationHeight;
         if (theImgBox)
             {
             // Mini-buttons (side label slice) for ruler
@@ -4914,45 +4740,44 @@
             {                   // advanced features off  // TODO: Should remove wasted pixels too
             drawGrayButtonBox(hvgSide, trackTabX, y, trackTabWidth, height, TRUE);
             }
         mapBoxTrackUi(hvgSide, trackTabX, y, trackTabWidth, height,
                       RULER_TRACK_NAME, RULER_TRACK_LABEL, "ruler");
         y += height + 1;
         }
 
     for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
         {
         track = flatTrack->track;
         int h, yStart = y, yEnd;
         if (track->limitedVis != tvHide)
             {
             // ORIG y += trackPlusLabelHeight(track, fontHeight);
-	    y += flatTrack->maxHeight;  // DEBUG REMOVE
+	    y += flatTrack->maxHeight;
             yEnd = y;
             h = yEnd - yStart - 1;
 
             /* alternate button colors for track groups*/
             if (track->group != lastGroup)
                 grayButtonGroup = !grayButtonGroup;
             lastGroup = track->group;
             if (theImgBox)
                 {
                 // Mini-buttons (side label slice) for tracks
                 sliceHeight      = yEnd - yStart;
                 sliceOffsetY     = yStart - 1;
                 curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
-                //warn("GTEX 2: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
                 curSlice    = imgTrackSliceUpdateOrAdd(curImgTrack,stButton,NULL,NULL,
                                                        sliceWidth[stButton],sliceHeight,
                                                        sliceOffsetX[stButton],sliceOffsetY);
                 }
             else if (!trackImgOnly) // Side buttons only need to be drawn when drawing page
                 {                   // with js advanced features off
                 if (grayButtonGroup)
                     drawGrayButtonBox(hvgSide, trackTabX, yStart, trackTabWidth, h, track->hasUi);
                 else
                     drawBlueButtonBox(hvgSide, trackTabX, yStart, trackTabWidth, h, track->hasUi);
                 }
 
             if (track->hasUi)
                 {
                 if (tdbIsCompositeChild(track->tdb))
@@ -4962,51 +4787,49 @@
                                   parent->track, parent->shortLabel, track->track);
                     }
                 else
                     mapBoxTrackUi(hvgSide, trackTabX, yStart, trackTabWidth, h, track->track,
                                   track->shortLabel, track->track);
                 }
             }
         }
     butOff = trackTabX + trackTabWidth;
     leftLabelX += butOff;
     leftLabelWidth -= butOff;
     }
 
 
 /* Draw left labels. */
-if (galtDebug)
-warn("Draw left labels");
+
 if (withLeftLabels)
     {
     if (theImgBox == NULL)
         {
         Color lightRed = hvGfxFindColorIx(hvgSide, 255, 180, 180);
 
         hvGfxBox(hvgSide, leftLabelX + leftLabelWidth, 0,
                  gfxBorder, pixHeight, lightRed);
         }
     y = gfxBorder;
     if (rulerMode != tvHide)
         {
         if (theImgBox)
             {
             // side label slice for ruler
             sliceHeight      = basePositionHeight + (rulerCds ? rulerTranslationHeight : 0) + 1;
             sliceOffsetY     = 0;
             curImgTrack = imgBoxTrackFind(theImgBox,NULL,RULER_TRACK_NAME);
-                //warn("GTEX 3: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
             curSlice    = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL,
                                                    sliceWidth[stSide],sliceHeight,
                                                    sliceOffsetX[stSide],sliceOffsetY);
             (void) sliceMapFindOrStart(curSlice,RULER_TRACK_NAME,NULL); // No common linkRoot
             }
         if (baseTitle)
             {
             hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, titleHeight,
                            MG_BLACK, font, WIN_TITLE_LABEL);
             y += titleHeight;
             }
         if (baseShowPos||baseShowAsm)
             {
             hvGfxTextRight(hvgSide, leftLabelX, y, leftLabelWidth-1, showPosHeight,
                            MG_BLACK, font, WIN_POS_LABEL);
@@ -5049,72 +4872,67 @@
             if (zoomedToBaseLevel)
                 y += baseHeight;
             }
         if (rulerCds)
             y += rulerTranslationHeight;
         }
     for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
         {
         track = flatTrack->track;
         if (track->limitedVis == tvHide)
             continue;
         if (theImgBox)
             {
             // side label slice for tracks
             //ORIG sliceHeight      = trackPlusLabelHeight(track, fontHeight);
-	    sliceHeight      = flatTrack->maxHeight;  // DEBUG REMOVE
+	    sliceHeight      = flatTrack->maxHeight;
             sliceOffsetY     = y;
             curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
-                //warn("GTEX 4: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
             curSlice    = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL,
                                                    sliceWidth[stSide],sliceHeight,
                                                    sliceOffsetX[stSide],sliceOffsetY);
             (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
             }
         if (trackShouldUseAjaxRetrieval(track))
             y += REMOTE_TRACK_HEIGHT;
         else
             {
         #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
             if (theImgBox && track->limitedVis != tvDense)
                 y += sliceHeight;
             else
         #endif ///def IMAGEv2_NO_LEFTLABEL_ON_FULL
 		{
 		setGlobalsFromWindow(windows); // use GLOBALS from first window
 		int ynew = doLeftLabels(track, hvgSide, font, y);
-		//setGlobalsFromWindow(windows); // first window  // REMOVE? this is the same as above
-
-		y += flatTrack->maxHeight;  // DEBUG REMOVE
+		y += flatTrack->maxHeight;
 		if ((ynew - y) > flatTrack->maxHeight)
 		    { // TODO should be errAbort?
 		    warn("doLeftLabels(y=%d) returned new y value %d that is too high - should be %d at most.", 
 			y, ynew, flatTrack->maxHeight);
 		    }
 		}
             }
         }
     }
 else
     {
     leftLabelX = leftLabelWidth = 0;
     }
 
 
 /* Draw guidelines. */
-if (galtDebug)
-warn("Draw guidelines");  // OR window separators in virtMode multi-window mode
 
 if (virtMode && emAltHighlight)
     withGuidelines = TRUE;  // we cannot draw the alternating backgrounds without guidelines layer
 
 if (withGuidelines)
     {
     struct hvGfx *bgImg = hvg; // Default to the one image
     boolean exists = FALSE;
     if (theImgBox)
         {
         struct tempName gifBg;
         char base[64];
 	if (virtMode) // window separators
 	    {
 	    safecpy(base,sizeof(base),"winSeparators");  // non-reusable temp file 
@@ -5169,187 +4987,160 @@
 	    {
 	    int x;
 	    Color lightBlue = hvGfxFindRgb(bgImg, &guidelineColor);
 	    for (x = fullInsideX+guidelineSpacing-1; x<pixWidth; x += guidelineSpacing)
 		hvGfxBox(bgImg, x, 0, 1, pixHeight, lightBlue);
 	    }
 
         hvGfxUnclip(bgImg);
         if (bgImg != hvg)
             hvGfxClose(&bgImg);
         }
     }
 
 
 /* Draw ruler */
-if (galtDebug)
-warn("Draw rulers");
 
-/* Show ruler at top. */
 if (rulerMode != tvHide)
     {
     newWinWidth = calcNewWinWidth(cart,virtWinStart,virtWinEnd,fullInsideWidth);
 
     if (theImgBox)
 	{
 	// data slice for ruler
 	sliceHeight      = basePositionHeight + (rulerCds ? rulerTranslationHeight : 0) + 1;
 	sliceOffsetY     = 0;
 	curImgTrack = imgBoxTrackFind(theImgBox,NULL,RULER_TRACK_NAME);
-                //warn("GTEX 5: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
 	curSlice    = imgTrackSliceUpdateOrAdd(curImgTrack,stData,theOneImg,rulerTtl,
 					       sliceWidth[stData],sliceHeight,
 					       sliceOffsetX[stData],sliceOffsetY);
 	(void) sliceMapFindOrStart(curSlice,RULER_TRACK_NAME,NULL); // No common linkRoot
 	}
 
     // need to have real winBaseCount to draw ruler scale
 
     for (window=windows; window; window=window->next)
 	{
-
-	// DETAILS
-	//    warn("window : %s %s %s:%d-%d offset %d width %d window=%lu", // DEBUG REMOVE
-	//      window->organism, window->database, window->chromName, window->winStart+1, window->winEnd, 
-	//      window->insideX, window->insideWidth, (unsigned long) window);
-
 	setGlobalsFromWindow(window);
 
 	if (theImgBox)
 	    {
 	    // Show window positions as mouseover
 	    if (virtMode)
 		{
 		char position[256];
 		safef(position, sizeof position, "%s:%d-%d", window->chromName, window->winStart+1, window->winEnd);
 		int x = window->insideX;
 		if (revCmplDisp)
 		    x = tl.picWidth - (x + window->insideWidth); 
 		imgTrackAddMapItem(curImgTrack, "#", position, 
 		    x, sliceOffsetY, x+window->insideWidth, sliceOffsetY+sliceHeight, RULER_TRACK_NAME);
 		}
 
 	    }
 
 	y = doDrawRuler(hvg,&rulerClickHeight,rulerHeight,yAfterRuler,yAfterBases,font,
 			fontHeight,rulerCds, scaleBarTotalHeight, window);
 	}
 
     setGlobalsFromWindow(windows); // first window
 
     }
 
 
 
 /* Draw center labels. */
-if (galtDebug)
-warn("Draw center labels.");
+
 if (withCenterLabels)
     {
-    setGlobalsFromWindow(windows); // use GLOBALS from first window
+    setGlobalsFromWindow(windows); // first window
 
     hvGfxSetClip(hvg, fullInsideX, gfxBorder, fullInsideWidth, pixHeight - 2*gfxBorder);
     y = yAfterRuler;
     for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
         {
         track = flatTrack->track;
         if (track->limitedVis == tvHide)
             continue;
 
         if (theImgBox)
             {
             // center label slice of tracks Must always make, even if the centerLabel is empty
             sliceHeight      = fontHeight;
             sliceOffsetY     = y;
             curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
             curSlice    = imgTrackSliceUpdateOrAdd(curImgTrack,stCenter,theOneImg,NULL,
                                                    sliceWidth[stData],sliceHeight,
                                                    sliceOffsetX[stData],sliceOffsetY);
             (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
             if (isCenterLabelConditional(track)) // sometimes calls track height, especially when no data there
 		{
-		//warn("isCenterLabelConditional(track)=TRUE %s", track->track);
                 imgTrackUpdateCenterLabelSeen(curImgTrack,isCenterLabelConditionallySeen(track) ?
                                                                             clNowSeen : clNotSeen);
 		}
             }
         if (trackShouldUseAjaxRetrieval(track))
 	    {
-	    //warn("trackShouldUseAjaxRetrieval(%s)", track->track); // DEBUG REMOVE
             y += REMOTE_TRACK_HEIGHT;
 	    }
         else
 	    { 
 	    int savey = y; // GALT
-	    //warn("calling doCenterLabels fullInsideWidth=%d", fullInsideWidth); // DEBUG REMOVE
             y = doCenterLabels(track, track, hvg, font, y, fullInsideWidth); // calls track height
 	    // TODO GALT why do I just pass track here instead of parentTrack? Did I lose something?
 	    // have to look at old code to see.
-
-	    y = savey + flatTrack->maxHeight; // GALT
+	    y = savey + flatTrack->maxHeight;
 	    }
         }
     hvGfxUnclip(hvg);
 
     setGlobalsFromWindow(windows); // first window
     }
 
 
-//warn("Start window draw: %s:%d-%d offset %d width %d", 
-  //  chromName, winStart+1, winEnd, insideX, insideWidth);
-
 
 /* Draw tracks. */
 
-if (galtDebug)
-warn("Draw tracks");
-
-    {
+    { // brace allows local vars
     
     long lastTime = 0;
     y = yAfterRuler;
     if (measureTiming)
         lastTime = clock1000();
     for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
         {
         track = flatTrack->track;
 
 	// parallelize more this?:
 	
         //ORIG if (track->limitedVis == tvHide)
 	if (isLimitedVisHiddenForAllWindows(track))
             continue;
 
-	//warn("flatTrack->track->track: %s", flatTrack->track->track); // DEBUG REMOVE
-	//fflush(stdout); // DEBUG REMOVE
 
         int centerLabelHeight = (isCenterLabelIncluded(track) ? fontHeight : 0);
-	//warn("flatTrack->track->track: %s isCenterLabelIncluded(track): %d "
-	   // "trackPlusLabelHeight(track, fontHeight): %d", 
-	    //flatTrack->track->track, isCenterLabelIncluded(track), trackPlusLabelHeight(track, fontHeight)); // DEBUG REMOVE
         int yStart = y + centerLabelHeight;
         // ORIG int yEnd   = y + trackPlusLabelHeight(track, fontHeight);
-	int yEnd   = y + flatTrack->maxHeight;  // DEBUG REMOVE
+	int yEnd   = y + flatTrack->maxHeight;
         if (theImgBox)
             {
             // data slice of tracks
             sliceOffsetY     = yStart;
             sliceHeight      = yEnd - yStart - 1;
             curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
             if (sliceHeight > 0)
                 {
-                //warn("GTEX 7: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
                 curSlice    = imgTrackSliceUpdateOrAdd(curImgTrack,stData,theOneImg,NULL,
                                                        sliceWidth[stData],sliceHeight,
                                                        sliceOffsetX[stData],sliceOffsetY);
                 (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
                 }
             }
         if (trackShouldUseAjaxRetrieval(track))
             y += REMOTE_TRACK_HEIGHT;
         else
 	    { 
 	    int savey = y;
 	    struct track *winTrack;
 
 	    // do preDraw
 	    if (track->preDrawItems)
@@ -5368,133 +5159,128 @@
 			}
 		    }
 		}
 
 	    setGlobalsFromWindow(windows); // first window
 	    // do preDrawMultiRegion across all windows, e.g. wig autoScale
 	    if (track->preDrawMultiRegion)
 		{
 		track->preDrawMultiRegion(track);
 		}
 
 	    // doDrawItems
 	    for (window=windows, winTrack=track; window; window=window->next, winTrack=winTrack->nextWindow)
 		{
 		setGlobalsFromWindow(window);
-		//warn("Draw tracks track dump %s\n", makeTrackDumpLink(track)); // DEBUG REMOVE
 		if (winTrack->limitedVis == tvHide)
 		    {
 		    warn("Draw tracks skipping %s because winTrack->limitedVis=hide", winTrack->track);
 		    continue;
 		    }
 		if (insideWidth >= 1)  // do not try to draw if width < 1.
 		    {
 		    int ynew = doDrawItems(winTrack, hvg, font, y, &lastTime);
-		    //warn("y=%d ynew=%d (ynew-y)=%d flatTrack->maxHeight=%d", y, ynew, ynew - y, flatTrack->maxHeight);
 		    if ((ynew-y) > flatTrack->maxHeight)  // so compiler does not complain ynew is not used.
 			errAbort("oops track too high!"); 
 		    }
 		}
 	    setGlobalsFromWindow(windows); // first window
 	    y = savey + flatTrack->maxHeight;
 	    }
 
         if (theImgBox && track->limitedVis == tvDense && tdbIsCompositeChild(track->tdb))
             mapBoxToggleVis(hvg, 0, yStart,tl.picWidth, sliceHeight,track);
             // Strange mapBoxToggleLogic handles reverse complement itself so x=0,width=tl.picWidth
 
         if (yEnd != y)
             warn("Slice height for track %s does not add up.  Expecting %d != %d actual",
                  track->shortLabel, yEnd - yStart - 1, y - yStart);
         }
     y++;
     }
 
-if (galtDebug)
-warn("post draw tracks leftLabels");
+/* post draw tracks leftLabels */
 
 /* if a track can draw its left labels, now is the time since it
  *  knows what exactly happened during drawItems
  */
 // TODO GALT Parellelize or not?
 if (withLeftLabels)
     {
     y = yAfterRuler;
     for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
         {
         track = flatTrack->track;
         if (track->limitedVis == tvHide)
             continue;
         if (theImgBox)
             {
             // side label slice of tracks
             // ORIG sliceHeight      = trackPlusLabelHeight(track, fontHeight);
-	    sliceHeight      = flatTrack->maxHeight;  // DEBUG REMOVE
+	    sliceHeight      = flatTrack->maxHeight;
             sliceOffsetY     = y;
             curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
-                //warn("WARN 8: track %s, sliceHeight=%d\n", track->shortLabel, sliceHeight);
             curSlice    = imgTrackSliceUpdateOrAdd(curImgTrack,stSide,theSideImg,NULL,
                                                    sliceWidth[stSide],sliceHeight,
                                                    sliceOffsetX[stSide],sliceOffsetY);
             (void) sliceMapFindOrStart(curSlice,track->tdb->track,NULL); // No common linkRoot
             }
 
         if (trackShouldUseAjaxRetrieval(track))
             y += REMOTE_TRACK_HEIGHT;
     #ifdef IMAGEv2_NO_LEFTLABEL_ON_FULL
         else if (track->drawLeftLabels != NULL
              &&  (theImgBox == NULL || track->limitedVis == tvDense))
     #else ///ndef IMAGEv2_NO_LEFTLABEL_ON_FULL
         else if (track->drawLeftLabels != NULL)
     #endif ///ndef IMAGEv2_NO_LEFTLABEL_ON_FULL
 	    {  // TODO parallelize?
 	    setGlobalsFromWindow(windows);
             y = doOwnLeftLabels(track, hvgSide, font, y);
 	    setGlobalsFromWindow(windows); // first window
 	    }
         else
             // ORIG y += trackPlusLabelHeight(track, fontHeight);
-	    y += flatTrack->maxHeight;  // DEBUG REMOVE
+	    y += flatTrack->maxHeight;
         }
     }
 
 
 
 /* Make map background. */
-if (galtDebug)
-warn("Make map background");
+
 y = yAfterRuler;
 for (flatTrack = flatTracks; flatTrack != NULL; flatTrack = flatTrack->next)
     {
     track = flatTrack->track;
     if (track->limitedVis != tvHide)
         {
         if (theImgBox)
             {
             // Set imgTrack in case any map items will be set
             // ORIG sliceHeight      = trackPlusLabelHeight(track, fontHeight);
-	    sliceHeight      = flatTrack->maxHeight;  // DEBUG REMOVE
+	    sliceHeight      = flatTrack->maxHeight;
             sliceOffsetY     = y;
             curImgTrack = imgBoxTrackFind(theImgBox,track->tdb,NULL);
             }
 
 	// TODO Parallelize?
 	setGlobalsFromWindow(windows); // first window
         doTrackMap(track, hvg, y, fontHeight, trackPastTabX, trackPastTabWidth);
 
         // ORIG y += trackPlusLabelHeight(track, fontHeight);
-	y += flatTrack->maxHeight;  // DEBUG REMOVE
+	y += flatTrack->maxHeight;
         }
     }
 
 /* Finish map. */
 hPrintf("</MAP>\n");
 
 // turn off inPlaceUpdate when rows in imgTbl can arbitrarily reappear and disappear (see redmine #7306 and #6944)
 jsonObjectAdd(jsonForClient, "inPlaceUpdate", newJsonBoolean(withLeftLabels && withCenterLabels));
 jsonObjectAdd(jsonForClient, "rulerClickHeight", newJsonNumber(rulerClickHeight));
 if(newWinWidth)
     {
     jsonObjectAdd(jsonForClient, "newWinWidth", newJsonNumber(newWinWidth));
     }
 
 /* Save out picture and tell html file about it. */
@@ -5682,31 +5468,30 @@
     if (cgiVarExists("hgGenomeClick"))
 	makeHgGenomeTrackVisible(track);
     if (track->loadItems == NULL)
         warn("No load handler for %s; possible missing trackDb `type' or `subTrack' attribute", tdb->track);
     else if (track->drawItems == NULL)
         warn("No draw handler for %s", tdb->track);
     else
         slAddHead(pTrackList, track);
     }
 }
 
 void loadFromTrackDb(struct track **pTrackList)
 /* Load tracks from database, consulting handler list. */
 {
 char *trackNameFilter = cartOptionalString(cart, "hgt.trackNameFilter");
-//warn("DEBUG loadFromTrackDb:: hgt.trackNameFilter=%s\n", trackNameFilter); // DEBUG REMOVE GALT
 struct trackDb *tdbList;
 if(trackNameFilter == NULL)
     tdbList = hTrackDb(database);
 else
     tdbList = hTrackDbForTrack(database, trackNameFilter);
 addTdbListToTrackList(tdbList, trackNameFilter, pTrackList);
 }
 
 static int getScoreFilter(char *trackName)
 /* check for score filter configuration setting */
 {
 char optionScoreStr[256];
 
 safef(optionScoreStr, sizeof(optionScoreStr), "%s.scoreFilter", trackName);
 return cartUsualInt(cart, optionScoreStr, 0);
@@ -7470,31 +7255,30 @@
 
 /////////////////
 
 // NEED TO LOAD ALL WINDOWS NOW
 // 
 //   Need to load one window at a time!
 //
 //   The use of the global values for a window
 //   means that differerent threads cannot use different global window values.
 //   Threads must run on just one window value at a time.
 //
 //   Begin by making a copy of the track structure for visible tracks
 //   for all windows.
 
 
-//warn("copy track structures for multiple  windows"); // DEBUG REMOVE
 // COPY TRACK STRUCTURES for other windows.
 
 // TODO: due to an issue where some loading code is modifying the visibility
 // of subtracks from hide to visible, I am forced to remove the optimization
 // of cloning ONLY non-hidden tracks and subtracks.  If the offending code
 // can be identified and moved into a step proceding the track cloning,
 // then we can return to that optimization. 
 //	if (track->visibility != tvHide)
 //		if (subtrack->visibility != tvHide)
 
 windows->trackList = trackList;  // save current track list in window
 struct window *window;
 for (window=windows; window->next; window=window->next)
     {
     struct track *newTrackList = NULL;
@@ -7520,52 +7304,44 @@
 		{
 		//if (subtrack->visibility != tvHide)  // Unable to use this optimization at present
 		    {
 		    struct track *subcopy;
 		    AllocVar(subcopy);
 		    memmove(subcopy,subtrack,sizeof(struct track));
 		    subcopy->next = NULL;
 		    subcopy->bbiFile = NULL;  // bigDataUrl custom tracks have already been opened, will re-open for other windows.
 		    subcopy->nextWindow = NULL;
 		    subcopy->prevWindow = subtrack;
 		    slAddHead(&copy->subtracks, subcopy);
 		    subtrack->nextWindow = subcopy;
 		    }
 		}
 	    slReverse(&copy->subtracks);
-	    //warn("%s track subs: %d  copy subs: %d", track->track, slCount(track->subtracks), slCount(copy->subtracks));
 	    }
 	}
     slReverse(&newTrackList);
     trackList = newTrackList;
     window->next->trackList = trackList;  // save new track list in window
     }
 trackList = windows->trackList;  // restore original track list
 
-// DEBUG REMOVE verify results.
-//for (window=windows; window; window=window->next)
-//    {
-//    warn("%s %d", window->chromName, slCount(window->trackList));
-//    }
-
 // Loop over each window loading all tracks
-//warn("Loop over each window loading all tracks"); // DEBUG REMOVE
 trackLoadingInProgress = TRUE;
 
 // TEMP HACK GALT REMOVE
 bool loadHack = FALSE; //TRUE;  // probably should only be tried on non-wiggle tracks
-//warn ("loadHack = %d", loadHack); // DEBUG REMOVE
+//warn ("loadHack = %d", loadHack); // TODO
 int lastWinEnd = 0;
 for (window=windows; window; window=window->next)
     lastWinEnd = window->winEnd;
 
 for (window=windows; window; window=window->next)
     {
     trackList = window->trackList;  // set track list
     setGlobalsFromWindow(window);
 
     // TEMP HACK GALT REMOVE
     if (loadHack)
 	{
 	if (currentWindow == windows) // first window
 	    winEnd = lastWinEnd; // so now we load the entire span inside the first window.
 	}
@@ -7585,96 +7361,77 @@
 	    AllocArray(threads, ptMax);
 	    /* Create threads */
 	    int pt;
 	    for (pt = 0; pt < ptMax; ++pt)
 		{
 		int rc = pthread_create(&threads[pt], NULL, remoteParallelLoad, &threads[pt]);
 		if (rc)
 		    {
 		    errAbort("Unexpected error %d from pthread_create(): %s",rc,strerror(rc));
 		    }
 		}
 	    }
 	}
 
     // TODO GALT
-    //warn("slCount(trackList) just before load regular tracks: %d", slCount(trackList)); // DEBUG REMOVE
-    int visCount = 0; // DEBUG REMOVE
     /* load regular tracks */
     for (track = trackList; track != NULL; track = track->next)
 	{
 	if (track->visibility != tvHide)
 	    {
-	    ++visCount; // DEBUG REMOVE
 	    if (!track->parallelLoading)
 		{
 		if (measureTiming)
 		    lastTime = clock1000();
 
-		//warn("load regular tracks BEFORE load and check max window to draw %s\n", makeTrackDumpLink(track)); // DEBUG REMOVE
 		checkMaxWindowToDraw(track);
 
-		//warn("load regular tracks BEFORE check if wiggling %s\n", makeTrackDumpLink(track)); // DEBUG REMOVE
 		checkIfWiggling(cart, track);
 
-		//warn("load regular tracks ABOUT to call loadItems() %s\n", makeTrackDumpLink(track)); // DEBUG REMOVE
-
 		if (!loadHack)
 		    {
-		    track->loadItems(track); // DEBUG RESTORE !!!
+		    track->loadItems(track);
 		    }
 		else
 		    {
 		    // TEMP HACK GALT REMOVE
 		    if (currentWindow == windows) // first window
 			{
 			track->loadItems(track);
 			}
 		    else
 			{
 			track->items = track->prevWindow->items;  // just point to the previous windows items (faster than loading)
 			// apparently loadItems is setting some other fields that we want, but which ones?
 			track->visibility = track->prevWindow->visibility;
 			track->limitedVis = track->prevWindow->limitedVis;
 			track->limitedVisSet = track->prevWindow->limitedVisSet;
 			track->height = track->prevWindow->height;
 			track->lineHeight = track->prevWindow->lineHeight;
 			track->heightPer = track->prevWindow->heightPer;
 			// TODO does this work for subtracks or parents/children?
 			}
 		    }
 
-		// DEBUG REMOVE how many visible subtracks?
-		int visSubCount = 0;
-		struct track *sub;
-		for (sub=track->subtracks; sub; sub=sub->next)
-		    if (sub->visibility != tvHide)
-			++visSubCount;
-
-		//warn("load regular tracks AFTER loadItems #%d %s type %s subtracks %d vis %d %s\n", 
-		    //visCount, track->track, trackDbSetting(track->tdb, "type"),
-			//slCount(track->subtracks), visSubCount, makeTrackDumpLink(track)); // DEBUG REMOVE
-
 		if (measureTiming)
 		    {
 		    thisTime = clock1000();
 		    track->loadTime = thisTime - lastTime;
 		    }
 		}
 	    }
 	}
-    //warn("after load regular tracks: %d", visCount); // DEBUG REMOVE
 
     if (ptMax > 0)
 	{
 	// TODO GALT parallel actually not sure if anything to worry about here
 	/* wait for remote parallel load to finish */
 	remoteParallelLoadWait(atoi(cfgOptionDefault("parallelFetch.timeout", "90")));  // wait up to default 90 seconds.
 	if (measureTiming)
 	    measureTime("Waiting for parallel (%d threads for %d tracks) remote data fetch", ptMax, pfdListCount);
 	}
 
     }
 trackLoadingInProgress = FALSE;
 
 setGlobalsFromWindow(windows); // first window // restore globals
 trackList = windows->trackList;  // restore track list
@@ -7721,45 +7478,36 @@
         }
     }
 
 if (theImgBox)
     {
     // If a portal was established, then set the global dimensions back to the portal size
     if (imgBoxPortalDimensions(theImgBox,NULL,NULL,NULL,NULL,&virtWinStart,&virtWinEnd,&(tl.picWidth),NULL))
         {
         virtWinBaseCount = virtWinEnd - virtWinStart;
         fullInsideWidth = tl.picWidth-gfxBorder-fullInsideX;
         }
     }
 /* Center everything from now on. */
 hPrintf("<CENTER>\n");
 
-// OLD WAY
-//jsonObjectAdd(jsonForClient, "winStart", newJsonNumber(winStart));
-//jsonObjectAdd(jsonForClient, "winEnd", newJsonNumber(winEnd));
-//jsonObjectAdd(jsonForClient, "chromName", newJsonString(chromName));
 
-// DONE instead of trying to add new variables here,
-// see if we can pass the virt versions in as if they were the original variables.
-// That way less of hgTracks.js would need to be changed.
 jsonObjectAdd(jsonForClient, "winStart", newJsonNumber(virtWinStart));
 jsonObjectAdd(jsonForClient, "winEnd", newJsonNumber(virtWinEnd));
 jsonObjectAdd(jsonForClient, "chromName", newJsonString(virtChromName));
 
 // Tell javascript about multiple windows info
-// GALT TODO if end up not using this information, turn this off
-// as it sends several K of extra data on a view with many windows.
 if (virtMode)
     {
     // pre windows
     long preVWinStart = virtWinStart - virtWinBaseCount;
     if (preVWinStart < 0)
 	preVWinStart = 0;
     long preVWinEnd = virtWinStart;
     struct window *preWindows = makeWindowListFromVirtChrom(preVWinStart, preVWinEnd);
     struct jsonElement *jsonForList = newJsonList(NULL);
     for(window=preWindows;window;window=window->next)
 	{
 	struct jsonElement *jsonForWindow = NULL;
 	jsonForWindow = newJsonObject(newHash(8));
 	jsonObjectAdd(jsonForWindow, "chromName",   newJsonString(window->chromName));
 	jsonObjectAdd(jsonForWindow, "winStart",    newJsonNumber(window->winStart));
@@ -7918,31 +7666,30 @@
     if (showTrackControls)
         {
 	/* Break into a second form so that zooming and scrolling
 	 * can be done with a 'GET' so that user can back up from details
 	 * page without Internet Explorer popping up an annoying dialog.
 	 * Do rest of page as a 'POST' so that the ultra-long URL from
 	 * all the track controls doesn't break things.  IE URL limit
 	 * is 2000 bytes, but some firewalls impose a ~1000 byte limit.
 	 * As a side effect of breaking up the page into two forms
 	 * we need to repeat the position in a hidden variable here
 	 * so that zoom/scrolling always has current position to work
 	 * from. */
         // This 'dirty' field is used to check if js/ajax changes to the page have occurred.
         // If so and it is reached by the back button, a page reload will occur instead.
 	char buf[256];
-	// DEBUG RESTORE
 	if (virtualSingleChrom()) // DISGUISE VMODE
 	    safef(buf, sizeof buf, "%s", windowsSpanPosition());
 	else
 	    safef(buf, sizeof buf, "%s:%ld-%ld", virtChromName, virtWinStart+1, virtWinEnd);
         hPrintf("<INPUT TYPE='text' style='display:none;' name='dirty' id='dirty' VALUE='false'>\n");
         hPrintf("<INPUT TYPE=HIDDEN id='positionHidden' name='position' "
                 "VALUE=\"%s\">", buf);
         hPrintf("\n%s", trackGroupsHidden1->string);
         hPrintf("</CENTER></FORM>\n");
         hPrintf("<FORM ACTION=\"%s\" NAME=\"TrackForm\" id=\"TrackForm\" METHOD=\"POST\">\n\n",
                 hgTracksName());
 	    hPrintf("%s", trackGroupsHidden2->string);
 	    freeDyString(&trackGroupsHidden1);
 	    freeDyString(&trackGroupsHidden2);
 	if (!psOutput) cartSaveSession(cart);   /* Put up hgsid= as hidden variable. */
@@ -7950,31 +7697,30 @@
 	}
 
 
     /* Make line that says position. */
 	{
 	char buf[256];
 	char *survey = cfgOptionEnv("HGDB_SURVEY", "survey");
 	char *surveyLabel = cfgOptionEnv("HGDB_SURVEY_LABEL", "surveyLabel");
 	    char *javascript = "onchange=\"document.location = '/cgi-bin/hgTracks?db=' + document.TrackForm.db.options[document.TrackForm.db.selectedIndex].value;\"";
 	    if (containsStringNoCase(database, "zoo"))
 		{
 		hPuts("Organism ");
 		printAssemblyListHtmlExtra(database, javascript);
 		}
 
-	// DEBUG RESTORE
 	if (virtualSingleChrom()) // DISGUISE VMODE
 	    safef(buf, sizeof buf, "%s", windowsSpanPosition());
 	else
 	    safef(buf, sizeof buf, "%s:%ld-%ld", virtChromName, virtWinStart+1, virtWinEnd);
 	
 	position = cloneString(buf);
 	hPrintf("<span class='positionDisplay' id='positionDisplay' title='click to copy position to input box'>%s</span>", addCommasToPos(database, position));
 	hPrintf("<input type='hidden' name='position' id='position' value='%s'>\n", buf);
 	sprintLongWithCommas(buf, virtWinEnd - virtWinStart);
 	hPrintf(" <span id='size'>%s</span> bp. ", buf);
 	hPrintf("<input class='positionInput' type='text' name='hgt.positionInput' id='positionInput' size='60'>\n");
 	hWrites(" ");
 	hButton("hgt.jump", "go");
 	if (!trackHubDatabase(database))
 	    {
@@ -8429,32 +8175,30 @@
 /* Scroll percentage of visible window. */
 {
 long offset;
 long newStart, newEnd;
 if (revCmplDisp)
     amount = -amount;
 offset = (long)(amount * virtWinBaseCount);
 /* Make sure don't scroll of ends. */
 newStart = virtWinStart + offset;
 newEnd = virtWinEnd + offset;
 if (newStart < 0)
     offset = -virtWinStart;
 else if (newEnd > virtSeqBaseCount)
     offset = virtSeqBaseCount - virtWinEnd;
 
-//warn("\nGALT relativeScroll %f results in offset %ld to apply to virtWinStart,End\n", amount, offset); // DEBUG REMOVE
-
 /* Move window. */
 virtWinStart += offset;
 virtWinEnd += offset;
 }
 
 void dinkWindow(boolean start, long dinkAmount)
 /* Move one end or other of window a little. */
 {
 if (revCmplDisp)
     {
     start = !start;
     dinkAmount = -dinkAmount;
     }
 if (start)
     {
@@ -8643,39 +8387,30 @@
 }
 
 boolean findNearestVirtMatch(char *chrom, int start, int end, boolean findNearest, long *retVirtStart, long *retVirtEnd)
 /* find nearest match on virt chrom. 
  * findNearest flag means of no direct hits found, take the closest miss. */
 {
 // search for one or more overlapping windows
 struct positionMatch *mList = virtChromSearchForPosition(chrom, start, end, findNearest);
 
 // sort positions by virtPos (will be sorted by chrom, start, end)
 matchSortOnVPos(&mList);
 
 // merge contiguous matches spanning multiple touching windows
 mList = matchMergeContiguousVPos(mList);
 
-// DEBUG SHOW matching regions found.
-//warn("DEBUG mList post-sort-merge search positions: %d", slCount(mList));
-//struct positionMatch *m;
-//for (m=mList; m; m=m->next)
-    //{
-    //long span = m->virtEnd - m->virtStart; 
-    //warn("virtStar=%ld virtEnd=%ld span=%ld", m->virtStart, m->virtEnd, span);
-    //}
-
 // TODO search for the best match in pList
 // TODO this is crude, needs to fix, just finds the largest match:
 struct positionMatch *p, *best = NULL;
 long bigSpan = 0;
 for (p=mList; p; p=p->next)
     {
     long span = p->virtEnd - p->virtStart; 
     if (span > bigSpan)
 	{
 	bigSpan = span;
 	best = p;
 	}
     }
 if (best) // TODO do something better
     {
@@ -8684,185 +8419,165 @@
     *retVirtEnd   = best->virtEnd;
     }
 else
     { 
     return FALSE;
     }
 return TRUE;
 }
 
 void remapHighlightPos()
 // Remap non-virt highlight position if any to new virtMode chrom.
 {
 if (virtualSingleChrom())
     return;
 struct highlightVar *h = parseHighlightInfo();
-//warn("remapHighlightPos h-> chrom=%s chromStart=%ld chromEnd=%ld", h->chrom, h->chromStart, h->chromEnd); // DEBUG REMOVE
 if (h && h->db && sameString(h->db, database))
     {
     long virtStart = 0, virtEnd = 0;
     if (findNearestVirtMatch(h->chrom, h->chromStart, h->chromEnd, FALSE, &virtStart, &virtEnd)) // try to find the nearest match
 	{
 	// save new highlight position to cart var
 	char cartVar[1024];
 	safef(cartVar, sizeof cartVar, "%s.%s:%ld-%ld#%s", h->db, "virt", virtStart, virtEnd, h->hexColor);
 	cartSetString(cart, "highlight", cartVar);
 	}
     else
 	{
 	// erase the highlight cartvar if it has no overlap with the new virt chrom
 	cartRemove(cart, "highlight");
 	}
     }
 }
 
 
 void tracksDisplay()
 /* Put up main tracks display. This routine handles zooming and
  * scrolling. */
 {
-//warn("top of tracksDisplay()\n"); // DEBUG REMOVE
-//warn("<a href=cartDump?hgsid=%s target=_blank>cartdump</a>", cartSessionId(cart)); // DEBUG REMOVE
 char *defaultPosition = hDefaultPos(database);
 char titleVar[256];
 char *oldPosition = cartUsualString(cart, "oldPosition", "");
 boolean findNearest = cartUsualBoolean(cart, "findNearest", FALSE);
 cartRemove(cart, "findNearest");
-//warn("findNearest = %d\n", findNearest); // DEBUG REMOVE
 
 boolean positionIsVirt = FALSE;
 position = getPositionFromCustomTracks();
 if (NULL == position)
     {
-    //warn("cartGetPosition: database=%s position=%s", database, position); // DEBUG REMOVE
     position = cartGetPosition(cart, database, &lastDbPosCart);
     if (sameOk(cgiOptionalString("position"), "lastDbPos"))
 	{
-	// DEBUG REMOVE
-	//struct dyString *encoded = newDyString(4096);
-	//cartEncodeState(lastDbPosCart, encoded);
-	//warn("restored lastDbPosCart encoded state = [%s]", encoded->string); // DEBUG REMOVE
         restoreSavedVirtPosition();
 	}
-    //warn("position = %s\n", position); // DEBUG REMOVE
     if (startsWith("virt:", position))
 	{
 	position = stripCommas(position); // sometimes the position string arrives with commas in it.
-	//warn("positionIsVirt=TRUE position = %s\n", position); // DEBUG REMOVE
 	positionIsVirt = TRUE;
 	}
     }
 
 
 if (sameString(position, ""))
     {
     hUserAbort("Please go back and enter a coordinate range or a search term in the \"search term\" field.<br>For example: chr22:20100000-20200000.\n");
     }
 
 if (!positionIsVirt)
     {
     chromName = NULL;
     winStart = 0;
     if (isGenome(position) || NULL ==
 	(hgp = findGenomePos(database, position, &chromName, &winStart, &winEnd, cart)))
 	{
-	//warn("doing weird stuff with isGenome() and findGenomePos(), add more debugging");
 	if (winStart == 0)  /* number of positions found */
 	    {
 	    freeMem(position);
 	    position = cloneString(cartUsualString(cart, "lastPosition", defaultPosition));
 	    hgp = findGenomePos(database, position, &chromName, &winStart, &winEnd,cart);
 	    if (hgp != NULL && differentString(position, defaultPosition))
 		cartSetString(cart, "position", position);
 	    }
 	}
 
     /* After position is found set up hash of matches that should
        be drawn with names highlighted for easy identification. */
     createHgFindMatchHash();
 
     /* This means that no single result was found
     I.e., multiple results may have been found and are printed out prior to this code*/
     if (NULL == chromName)
 	{
 	// In case user manually edits the browser location as described in #13009,
 	// revert the position.  If they instead choose from the list as we expect,
 	// that will set the position to their choice.
 	// lastPosition gets set in cart.c
 	char *lastPosition = cartUsualString(cart, "lastPosition", hDefaultPos(database));
 	cartSetString(cart, "position", lastPosition);
 	return;
 	}
 
     }
 
 virtMode = cartUsualBoolean(cart, "virtMode", FALSE);
-//warn("virtMode=%d\n", virtMode); // DEBUG REMOVE
 
 /* Figure out basic dimensions of display.  This
  * needs to be done early for the sake of the
  * zooming and dinking routines. */
 setLayoutGlobals();
-//warn("after setLayoutGlobals() fullInsideX=%d fullInsideWidth=%d tl.picWidth=%d gfxBorder=%d\n", 
-    //fullInsideX, fullInsideWidth, tl.picWidth, gfxBorder); // DEBUG REMOVE
 
 virtModeType = cartUsualString(cart, "virtModeType", virtModeType);
-//warn("virtModeType=%s\n", virtModeType); // DEBUG REMOVE
 
 if (positionIsVirt && virtualSingleChrom())
     {
     // we need chromName to be set before initRegionList() gets called.
     position = cartUsualString(cart, "nonVirtPosition", "");
-    //warn("positionIsVirt && virtualSingleChrom(), going to nonVirtPosition %s", position);  // DEBUG REMOVE
     if (!sameString(position,""))
 	parseNonVirtPosition(position);
     }
-//warn("chromName=%s", chromName); // DEBUG REMOVE
 
 // TODO GALT do we need to add in other types that now depend on emGeneTable too? maybe singleTrans?
+//   OR maybe this code should just be part of initRegionList()
 if (sameString(virtModeType, "exonMostly") || sameString(virtModeType, "geneMostly")) 
     {
     setEMGeneTrack();
     if (!emGeneTable) // there is no available gene table, undo exonMostly or geneMostly
 	{
 	//warn("setEMGeneTrack unable to find default gene track");
 	virtModeType = "default";
 	cartSetString(cart, "virtModeType", virtModeType); 
 	}
     }
 
 lastVirtModeType = cartUsualString(cart, "lastVirtModeType", lastVirtModeType); 
 
 while(TRUE)
     {
-    //warn("virtModeType=%s lastVirtModeType=%s\n", virtModeType, lastVirtModeType); // DEBUG REMOVE
     if (sameString(virtModeType, "default") && !(sameString(lastVirtModeType, "default")))
 	{ // RETURNING TO DEFAULT virtModeType
 	virtModeType = "default";
 	cartSetString(cart, "virtModeType", virtModeType); 
 	findNearest = TRUE;
 	if (positionIsVirt)
 	    position = cartUsualString(cart, "nonVirtPosition", "");
 	char *nvh = cartUsualString(cart, "nonVirtHighlight", NULL);
 	if (nvh)
 	    cartSetString(cart, "highlight", nvh); 
-	//warn("leaving virtMode, going to position %s", position);  // DEBUG REMOVE
 	if (!sameString(position,""))
 	    parseNonVirtPosition(position);
 	}
 
-    //warn("\nGALT before initRegionList chromName=%s winStart=%d winEnd=%d\n", chromName, winStart,winEnd); // DEBUG REMOVE
     if (initRegionList())   // initialize the region list, sets virtModeExtraState
 	{
 	break;  
 	}
     else
 	{ // virt mode failed, forced to return to default
 	virtModeType = "default";
 	cartSetString(cart, "virtModeType", virtModeType);
 	position = cloneString(hDefaultPos(database));
 	hgp = findGenomePos(database, position, &chromName, &winStart, &winEnd, cart);
 	cartSetString(cart, "position", position);
 	positionIsVirt=FALSE;
 	virtMode=FALSE;
 	}
     }
@@ -8875,113 +8590,105 @@
 
 makeVirtChrom();
 
 //testVirtChromBinarySearch();
 
 // ajax callback to convert chrom position to virt chrom position
 if (cartVarExists(cart, "hgt.convertChromToVirtChrom")) 
     {
     position = cartString(cart, "hgt.convertChromToVirtChrom");
     char nvh[256];
     safef(nvh, sizeof nvh, "%s.%s", database, position);
     cartSetString(cart, "nonVirtHighlight", nvh);
     parseNonVirtPosition(position);
     if (findNearestVirtMatch(chromName, winStart, winEnd, FALSE, &virtWinStart, &virtWinEnd))
 	{
-	//hPrintf("<p id=virtWinStart>%ld</p><br>\n", virtWinStart);
-	//hPrintf("<p id=virtWinEnd>%ld</p><br>\n", virtWinEnd);
 	struct jsonElement *jsonForConvert = NULL;
 	jsonForConvert = newJsonObject(newHash(8));
 	jsonObjectAdd(jsonForConvert, "virtWinStart", newJsonNumber(virtWinStart));
 	jsonObjectAdd(jsonForConvert, "virtWinEnd", newJsonNumber(virtWinEnd));
 	hPrintf("<script type='text/javascript'>\n");
 	jsonPrint((struct jsonElement *) jsonForConvert, "convertChromToVirtChrom", 0);
 	hPrintf("</script>\n");
 	}
     return;
     }
 
 lastVirtModeExtraState = cartUsualString(cart, "lastVirtModeExtraState", lastVirtModeExtraState); 
-//warn("\nGALT virtModeExtraState=%s lastVirtModeExtraState=%s\n", virtModeExtraState, lastVirtModeExtraState); // DEBUG REMOVE
 
 // DISGUISED POSITION
 if (!startsWith("virt:", position) && (virtualSingleChrom()))
     {
-    //warn("virtualSingleChrom trying to find best vchrom location corresponding to chrom=%s, winStart=%d, winEnd=%d\n", chromName, winStart, winEnd); // DEBUG REMOVE
+    // "virtualSingleChrom trying to find best vchrom location corresponding to chromName, winStart, winEnd
     findNearest = TRUE;
 
-    if (!(chromName && findNearestVirtMatch(chromName, winStart, winEnd, findNearest, &virtWinStart, &virtWinEnd))) // try to find the nearest match
+     // try to find the nearest match
+    if (!(chromName && findNearestVirtMatch(chromName, winStart, winEnd, findNearest, &virtWinStart, &virtWinEnd)))
 	{ // create 1k window near middle of vchrom
-	warn("Unable to find any region near the position on the chromosome in the multi-regions. Now using middle of view."); // KEEP?
+	warn("Unable to find any region near the position on the chromosome in the multi-regions. Now using middle of view.");
 	virtWinStart = virtSeqBaseCount / 2;
 	virtWinEnd = virtWinStart + 1000;
 	if (virtWinEnd > virtSeqBaseCount)
 	    virtWinEnd = virtSeqBaseCount;
 	}
     virtMode = TRUE;
     }
 
 // when changing modes (or state like padding), first try to revert to plain non-virt position 
 if (!sameString(virtModeType, "default")
  && !sameString(lastVirtModeType, "default")
  && !(sameString(virtModeType, lastVirtModeType) && sameString(virtModeExtraState, lastVirtModeExtraState)))
     { // CHANGE FROM ONE NON-DEFAULT virtMode to another.
     virtChromChanged = TRUE;    // virtChrom changed
     lastVirtModeType = "default";
     cartSetString(cart, "lastVirtModeType", lastVirtModeType); // I think I do not need this
     lastVirtModeExtraState = ""; 
     findNearest = TRUE;
     position = cartUsualString(cart, "nonVirtPosition", "");
-    //warn("leaving virtMode, going to position %s", position);  // DEBUG REMOVE
     if (!sameString(position,""))
 	parseNonVirtPosition(position);
     char *nvh = cartUsualString(cart, "nonVirtHighlight", "");
-    //warn("CHANGE FROM ONE NON-DEFAULT virtMode to another nvh=%s",nvh);  // DEBUG REMOVE
-    if (!sameString(nvh, "")) // DEBUG REMOVE? not needed probably
+    if (!sameString(nvh, "")) // REMOVE? not needed probably
 	{
 	cartSetString(cart, "highlight", nvh); 
 	}
     }
 
 // virt mode has not changed
 if (sameString(virtModeType, lastVirtModeType)
  && sameString(virtModeExtraState, lastVirtModeExtraState))
     {
     if (virtMode)
 	{
 	if (positionIsVirt)
 	    {
 	    parseVirtPosition(position);
-	    //warn("\nGALT after parseVirtPosition(%s), virtWinStart=%ld virtWinEnd=%ld\n", position, virtWinStart, virtWinEnd); // DEBUG REMOVE
 	    }
 	else
 	    {	
 	    // Is this a new position to navigate to
 	    // or just an old inherited position.
 	    position = stripCommas(position);  // sometimes the position string arrives with commas in it.
 	    if (!sameString(position, oldPosition))
 		{
-		//warn("\nGALT before virtChromSearchForPosition(), position=%s oldPosition=%s\n", position, oldPosition); // DEBUG REMOVE
-
-		//warn("\nGALT          chrom=%s, winStart=%d, winEnd=%d\n", chromName, winStart, winEnd); // DEBUG REMOVE
-
 		if (!findNearestVirtMatch(chromName, winStart, winEnd, findNearest, &virtWinStart, &virtWinEnd))
 		    {
 		    // errAbort has kind of harsh behavior, and does not work well with ajax anyways
 		    warn("Location not found in Multi-Region View. " 
-		    "To return to default view at that location, click <a href=%s?%s=%s&position=%s:%d-%d&virtModeType=default>here</a>.\n"
-		    , hgTracksName(), cartSessionVarName(), cartSessionId(cart), chromName, winStart+1, winEnd); // DEBUG REMOVE
+		    "To return to default view at that location, "
+		    "click <a href=%s?%s=%s&position=%s:%d-%d&virtModeType=default>here</a>.\n"
+		    , hgTracksName(), cartSessionVarName(), cartSessionId(cart), chromName, winStart+1, winEnd);
 		    // try to resume using oldPosition
 		    parseVirtPosition(oldPosition);
 		    }
 		}
 	    }
 	}
     else
 	{
 	if (positionIsVirt)
 	    errAbort("positionIsVirt=%d but virtMode=%d", positionIsVirt, virtMode);
 	}
 
 
     }
 else
@@ -8994,72 +8701,69 @@
 
 	}
     else
 	{
 
 	// ENTERING VIRTMODE
 
 	// First time initialization
 
 	findNearest = TRUE;
 
 	// For now, do this manually here:
 	// sets window to full genome size, which for these demos should be small except for allChroms
 	if (sameString(virtModeType, "exonMostly") || sameString(virtModeType, "geneMostly") || sameString(virtModeType, "kcGenes")) // create 1k window near middle of vchrom
 	    {
-	    //warn("trying to find best vchrom location corresponding to chrom=%s, winStart=%d, winEnd=%d\n", chromName, winStart, winEnd); // DEBUG REMOVE
-
-	    if (!(chromName && findNearestVirtMatch(chromName, winStart, winEnd, findNearest, &virtWinStart, &virtWinEnd))) // try to find the nearest match
+	    // trying to find best vchrom location corresponding to chromName, winStart, winEnd);
+	    // try to find the nearest match
+	    if (!(chromName && findNearestVirtMatch(chromName, winStart, winEnd, findNearest, &virtWinStart, &virtWinEnd))) 
 		{
-		warn("Unable to find any region near the position on the chromosome in the multi-regions. Now using middle of view."); // KEEP?
+		warn("Unable to find any region near the position on the chromosome in the multi-regions. Now using middle of view.");
 		virtWinStart = virtSeqBaseCount / 2;
 		virtWinEnd = virtWinStart + 1000;
 		if (virtWinEnd > virtSeqBaseCount)
 		    virtWinEnd = virtSeqBaseCount;
 		}
 	    virtMode = TRUE;
 	    }
 	else if (sameString(virtModeType, "singleAltHaplo"))
 	    {
 	    virtWinStart = defaultVirtWinStart;
 	    virtWinEnd = defaultVirtWinEnd;
 	    virtMode = TRUE;
 	    }
 	else if (!sameString(virtModeType, "default"))
 	    {
 	    virtWinStart = 0;
 	    virtWinEnd = virtSeqBaseCount;
 	    virtMode = TRUE;
 	    }
 
 	remapHighlightPos(); 
 
 	}
-    //warn("\nGALT default virtWinStart=%ld virtWinEnd=%ld\n", virtWinStart, virtWinEnd); // DEBUG REMOVE
 
     }
 
 if (virtMode)
     virtChromName = "virt";
 else
     virtChromName = chromName; 
 
 virtWinBaseCount = virtWinEnd - virtWinStart;
 
 
-//warn("\nGALT BEFORE navigation section, virtChromName=%s virtWinStart=%ld virtWinEnd=%ld\n", virtChromName, virtWinStart, virtWinEnd); // DEBUG REMOVE
-
 baseShowPos = cartUsualBoolean(cart, BASE_SHOWPOS, FALSE);
 baseShowAsm = cartUsualBoolean(cart, BASE_SHOWASM, FALSE);
 baseShowScaleBar = cartUsualBoolean(cart, BASE_SCALE_BAR, TRUE);
 baseShowRuler = cartUsualBoolean(cart, BASE_SHOWRULER, TRUE);
 safef(titleVar,sizeof(titleVar),"%s_%s", BASE_TITLE, database);
 baseTitle = cartUsualString(cart, titleVar, "");
 if (sameString(baseTitle, ""))
     baseTitle = NULL;
 
 if  (cgiVarExists("hgt.toggleRevCmplDisp"))
     toggleRevCmplDisp();
 setRulerMode();
 
 /* Do zoom/scroll if they hit it. */
 if (cgiVarExists("hgt.left3"))
@@ -9093,156 +8797,135 @@
 else if (cgiVarExists("hgt.dinkLL"))
     dinkWindow(TRUE, -dinkSize("dinkL"));
 else if (cgiVarExists("hgt.dinkLR"))
     dinkWindow(TRUE, dinkSize("dinkL"));
 else if (cgiVarExists("hgt.dinkRL"))
     dinkWindow(FALSE, -dinkSize("dinkR"));
 else if (cgiVarExists("hgt.dinkRR"))
     dinkWindow(FALSE, dinkSize("dinkR"));
 
 /* Before loading items, deal with the next/prev item arrow buttons if pressed. */
 if (cgiVarExists("hgt.nextItem"))
     doNextPrevItem(TRUE, cgiUsualString("hgt.nextItem", NULL));
 else if (cgiVarExists("hgt.prevItem"))
     doNextPrevItem(FALSE, cgiUsualString("hgt.prevItem", NULL));
 
-//warn("\nGALT BEFORE clipping section, virtChromName=%s virtWinStart=%ld virtWinEnd=%ld\n", virtChromName, virtWinStart, virtWinEnd); // DEBUG REMOVE
-
 
 /* Clip chromosomal position to fit. */
 if (virtWinEnd < virtWinStart)
     {
-    // swap start and end 
+    // swap start and end (user entered coordinates backwards)
     long temp = virtWinEnd;
     virtWinEnd = virtWinStart;
     virtWinStart = temp;
     }
 else if (virtWinStart == virtWinEnd)
     {
-    //warn("\nGALT weird virtWinStart == virtWinEnd = %ld\n", virtWinStart); // DEBUG REMOVE
     // Size 0 window
     virtWinStart -= 1;
     virtWinEnd += 1;
     }
 
 if (virtWinStart < 0)
     {
     virtWinStart = 0;
     }
 
 if (virtWinEnd > virtSeqBaseCount)
     {
     virtWinEnd = virtSeqBaseCount;
     }
 
 if (virtWinStart > virtSeqBaseCount)
     {
     virtWinStart = virtSeqBaseCount - 1000;
     }
 
 virtWinBaseCount = virtWinEnd - virtWinStart;
 if (virtWinBaseCount <= 0)
     hUserAbort("Window out of range on %s", virtChromName);
 
-//warn("\nGALT BEFORE portal start section, virtChromName=%s virtWinStart=%ld virtWinEnd=%ld\n", virtChromName, virtWinStart, virtWinEnd); // DEBUG REMOVE
-
 if (!cartUsualBoolean(cart, "hgt.psOutput", FALSE)
  && !cartUsualBoolean(cart, "hgt.imageV1" , FALSE))
     {
 
     // TODO GALT Guidelines broken on virtChrom for 3X.
     //  works in demo0 or real chrom. Only the guidelines seem to be messed up.
     //  Other stuff works. 1X works too. 
     // Since we are not using 3X for now, I will leave this for a future fix.
     // To test 3X, do make clean; make CFLAGS=-DIMAGEv2_DRAG_SCROLL_SZ=3
 
     // Start an imagebox (global for now to avoid huge rewrite of hgTracks)
     // Set up imgBox dimensions
     int sideSliceWidth  = 0;   // Just being explicit
     if (withLeftLabels)
         sideSliceWidth   = (fullInsideX - gfxBorder*3) + 2;
 
     //  for the 3X expansion effect to work, this needs to happen BEFORE we create the windows list
     //    in makeWindowListFromVirtChrom()
     theImgBox = imgBoxStart(database,virtChromName,virtWinStart,virtWinEnd,
                             (!revCmplDisp),sideSliceWidth,tl.picWidth);
     // Define a portal with a default expansion size,
     // then set the global dimensions to the full image size
     if (imgBoxPortalDefine(theImgBox,&virtWinStart,&virtWinEnd,&(tl.picWidth),0))
         {
         virtWinBaseCount = virtWinEnd - virtWinStart;
         fullInsideWidth = tl.picWidth - gfxBorder - fullInsideX;
         }
 
     }
 
-//warn("AFTER portal start section, virtChromName=%s virtWinStart=%ld virtWinEnd=%ld\n", virtChromName, virtWinStart, virtWinEnd); // DEBUG REMOVE
-
 
 // For portal 3x expansion to work right, it would have to take effect, at least temporarily,
 // right here before we call makeWindowListFromVirtChrom().
 windows = makeWindowListFromVirtChrom(virtWinStart, virtWinEnd); // creates windows, sets chrom, winStart, winEnd from virtual chrom
 if (slCount(windows) > 4000) // TODO a more graceful response
 	errAbort("Too many windows in view. Unable to display image at requested zoom level.");
 
-//warn("winCount=%d\n", slCount(windows));
-
-//warn("AFTER makeWindowListFromVirtChrom, virtChromName=%s virtWinStart=%ld virtWinEnd=%ld\n", virtChromName, virtWinStart, virtWinEnd); // DEBUG REMOVE
-
-
 allocPixelsToWindows(); // sets windows insideWidth and insideX
 
-//warn("AFTER allocPixelsToWindows, virtChromName=%s virtWinStart=%ld virtWinEnd=%ld\n", virtChromName, virtWinStart, virtWinEnd); // DEBUG REMOVE
-
-
-
 if (theImgBox)
     {
     // If a portal was established, then set the global dimensions back to the portal size
     if (imgBoxPortalDimensions(theImgBox,NULL,NULL,NULL,NULL,&virtWinStart,&virtWinEnd,&(tl.picWidth),NULL))
         {
         virtWinBaseCount = virtWinEnd - virtWinStart;
         fullInsideWidth = tl.picWidth-gfxBorder-fullInsideX;
         }
     }
 
-//warn("AFTER portal demensions section, virtChromName=%s virtWinStart=%ld virtWinEnd=%ld\n", virtChromName, virtWinStart, virtWinEnd); // DEBUG REMOVE
-
-
 setGlobalsFromWindow(windows); // first window
 
 seqBaseCount = hChromSize(database, chromName);
 
-//warn("virtWinStart=%ld virtWinEnd=%ld\n", virtWinStart, virtWinEnd); // DEBUG REMOVE
-//warn("virtWinBaseCount=%ld virtSeqBaseCount=%ld\n", virtWinBaseCount, virtSeqBaseCount); // DEBUG REMOVE
-
 /* Save computed position in cart. */
 cartSetString(cart, "org", organism);
 cartSetString(cart, "db", database);
 
 char newPos[256];
 
 // disguise the cart pos var
 if (virtualSingleChrom()) // DISGUISE VMODE
     safef(newPos, sizeof newPos, "%s", windowsSpanPosition());
 else // usual
     safef(newPos, sizeof newPos, "%s:%ld-%ld", virtChromName, virtWinStart+1, virtWinEnd);
 
 position = cloneString(newPos);
 cartSetString(cart, "position", position);
-cartSetString(cart, "oldPosition", position); // DEBUG REMOVE MAYBE
-//cartSetString(cart, "lastPosition", position); // DEBUG REMOVE TESTING.
+cartSetString(cart, "oldPosition", position);
+//cartSetString(cart, "lastPosition", position);  // this is set in cart.c
+// TODO GALT is it possible and worthwhile to just use lastPosition instead of oldPosition?
 
 cartSetBoolean(cart, "virtMode", virtMode);
 cartSetString(cart, "virtModeType", virtModeType); 
 virtModeType = cartString(cart, "virtModeType"); // refresh the pointer after changing hash
 
 
 lastVirtModeType=virtModeType;
 cartSetString(cart, "lastVirtModeType", lastVirtModeType);
 lastVirtModeType = cartString(cart, "lastVirtModeType"); // refresh 
 
 lastVirtModeExtraState=virtModeExtraState;
 cartSetString(cart, "lastVirtModeExtraState", lastVirtModeExtraState);
 lastVirtModeExtraState = cartString(cart, "lastVirtModeExtraState"); // refresh 
 
 
@@ -9258,36 +8941,30 @@
    nvh = nonVirtPositionFromHighlightPos();
 if (virtMode && nvh)
     cartSetString(cart, "nonVirtHighlight", nvh);  
 else
     cartRemove(cart, "nonVirtHighlight");
 
 // save lastDbPos. save the current position and other important cart vars related to virtual view.
 
 lastDbPosSaveCartSetting("position");
 lastDbPosSaveCartSetting("nonVirtPosition");
 lastDbPosSaveCartSetting("virtMode");
 lastDbPosSaveCartSetting("virtModeType");
 lastDbPosSaveCartSetting("lastVirtModeType");
 lastDbPosSaveCartSetting("lastVirtModeExtraState");
 
-// DEBUG REMOVE
-//struct dyString *encoded = newDyString(4096);
-//cartEncodeState(lastDbPosCart, encoded);
-//warn("lastDbPosCart encoded state = [%s]", encoded->string); // DEBUG REMOVE
-
-//warn("database=%s, position=%s, virtModeType=%s, virtModeExtraState=%s", database, position, virtModeType, virtModeExtraState); // DEBUG REMOVE
 cartSetDbPosition(cart, database, lastDbPosCart);
 
 if (cartUsualBoolean(cart, "hgt.psOutput", FALSE))
     handlePostscript();
 else
     doTrackForm(NULL, NULL);
 }
 
 void chromInfoTotalRow(int count, long long total)
 /* Make table row with total number of sequences and size from chromInfo. */
 {
 cgiSimpleTableRowStart();
 cgiSimpleTableFieldStart();
 printf("Total: %d", count);
 cgiTableFieldEnd();