85bd10da37f403d155c4434d90edcd146e682948
braney
  Mon May 15 13:03:32 2017 -0700
add sorting to composite wiggles.

diff --git src/hg/hgTracks/hgTracks.c src/hg/hgTracks/hgTracks.c
index 3ef530b..816cd88 100644
--- src/hg/hgTracks/hgTracks.c
+++ src/hg/hgTracks/hgTracks.c
@@ -4744,57 +4744,77 @@
 		// 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;
 		    }
 		}
 	    }
 	}
     }
 trackList = windows->trackList;
 setGlobalsFromWindow(windows); // first window
 
+struct slName *orderedWiggles = NULL;
+char *sortTrack;
+char *wigOrder = NULL;
+if ((sortTrack = cgiOptionalString( "sortSim")) != NULL)
+    {
+    char buffer[1024];
+    safef(buffer, sizeof buffer,  "simOrder_%s", sortTrack);
+    wigOrder = cartString(cart, buffer);
+    }
+
+if ((sortTrack = cgiOptionalString( "sortExp")) != NULL)
+    {
+    char buffer[1024];
+    safef(buffer, sizeof buffer,  "expOrder_%s", sortTrack);
+    wigOrder = cartString(cart, buffer);
+    }
+
+if (wigOrder != NULL)
+    orderedWiggles = slNameListFromString(wigOrder, ' ');
+
 // Construct flatTracks 
 for (track = trackList; track != NULL; track = track->next)
     {
     if (tdbIsComposite(track->tdb))
         {
         struct track *subtrack;
         if (isCompositeInAggregate(track))
-            flatTracksAdd(&flatTracks,track,cart);
+            flatTracksAdd(&flatTracks,track,cart, orderedWiggles);
         else
             {
             for (subtrack = track->subtracks; subtrack != NULL; subtrack = subtrack->next)
                 {
                 if (!isSubtrackVisible(subtrack))
                     continue;
 
                 if (!isLimitedVisHiddenForAllWindows(subtrack))
                     {
-                    flatTracksAdd(&flatTracks,subtrack,cart);
+                    flatTracksAdd(&flatTracks,subtrack,cart, orderedWiggles);
                     }
                 }
             }
         }
     else
 	{	
 	if (!isLimitedVisHiddenForAllWindows(track))
 	    {
-	    flatTracksAdd(&flatTracks,track,cart);
+	    flatTracksAdd(&flatTracks,track,cart, orderedWiggles);
 	    }
 	}
     }
 flatTracksSort(&flatTracks); // Now we should have a perfectly good flat track list!
 
 
 // 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)
 	{
 	continue;
 	}
@@ -5410,30 +5430,32 @@
 			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);
         }
+
+    calcWiggleOrdering(cart, flatTracks);
     y++;
     }
 
 /* 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;
@@ -9818,43 +9840,30 @@
 // tell UDC where to put its statistics file
 char *udcLogFile;
 if ((udcLogFile =  cfgOption("udcLog")) != NULL)
     {
     FILE *fp = mustOpen(udcLogFile, "a");
     udcSetLog(fp);
     }
 
 initTl();
 
 char *configPageCall = cartCgiUsualString(cart, "hgTracksConfigPage", "notSet");
 char *configMultiRegionPageCall = cartCgiUsualString(cart, "hgTracksConfigMultiRegionPage", "notSet");
 
 /* Do main display. */
 
-char *sortTrack;
-if ((sortTrack = cgiOptionalString( "sortSim")) != NULL)
-    {
-    printf("sort track by similarity %s\n", sortTrack);
-    //sortTrackByExpression(cart);
-    }
-
-if ((sortTrack = cgiOptionalString( "sortExp")) != NULL)
-    {
-    printf("sort track by expression %s\n", sortTrack);
-    //sortTrackByExpression(cart);
-    }
-
 if (cartUsualBoolean(cart, "hgt.trackImgOnly", FALSE))
     {
     trackImgOnly = TRUE;
     ideogramToo = cartUsualBoolean(cart, "hgt.ideogramToo", FALSE);
     hideControls = TRUE;
     withNextItemArrows = FALSE;
     withNextExonArrows = FALSE;
     hgFindMatches = NULL;     // XXXX necessary ???
     }
 
 jsonForClient = newJsonObject(newHash(8));
 jsonObjectAdd(jsonForClient, "cgiVersion", newJsonString(CGI_VERSION));
 boolean searching = differentString(cartUsualString(cart, TRACK_SEARCH,"0"), "0");
 
 if(!trackImgOnly)