352e4a03ec0521929355c33f57b113e3ce890afc
max
  Mon Jul 1 01:25:22 2024 -0700
adding hub tracks to DNA color options, refs #34009

diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index 60bd1c8..c14e3c3 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -5158,50 +5158,61 @@
 if (tdb->subtracks != NULL)
     return rFindUnderstandableTrack(db,tdb->subtracks);
 
 if (fbUnderstandTrack(db, tdb) && !dnaIgnoreTrack(tdb->table))
     return tdb;
 else
     return NULL;
 }
 
 boolean forestHasUnderstandableTrack(char *db, struct trackDb *tdb)
 // TRUE if any leaf is usable in getting DNA.
 {
 return (rFindUnderstandableTrack(db, tdb) != NULL);
 }
 
+struct trackDb* loadTracks()
+/* load native tracks, cts, userPsl and track Hubs and return tdbList */
+{
+struct trackDb *tdbList = hTrackDb(database);
+struct trackDb *ctdbList = tdbForCustomTracks();
+struct trackDb *utdbList = tdbForUserPsl();
+
+struct grp *pGrpList = NULL;
+struct trackDb *hubList = hubCollectTracks(database, &pGrpList);
+
+ctdbList = slCat(ctdbList, tdbList);
+ctdbList = slCat(ctdbList, hubList);
+tdbList = slCat(utdbList, ctdbList);
+return tdbList;
+}
+
 
 void doGetDnaExtended1()
 /* Do extended case/color get DNA options. */
 {
-struct trackDb *tdbList = hTrackDb(database), *tdb;
-struct trackDb *ctdbList = tdbForCustomTracks();
-struct trackDb *utdbList = tdbForUserPsl();
 boolean revComp  = cartUsualBoolean(cart, "hgSeq.revComp", FALSE);
 boolean maskRep  = cartUsualBoolean(cart, "hgSeq.maskRepeats", FALSE);
 int padding5     = cartUsualInt(cart, "hgSeq.padding5", 0);
 int padding3     = cartUsualInt(cart, "hgSeq.padding3", 0);
 int lineWidth    = cartUsualInt(cart, "lineWidth", 60);
 char *casing     = cartUsualString(cart, "hgSeq.casing", "");
 char *repMasking = cartUsualString(cart, "hgSeq.repMasking", "");
 boolean caseUpper= FALSE;
 char *pos = NULL;
 
-
-ctdbList = slCat(ctdbList, tdbList);
-tdbList = slCat(utdbList, ctdbList);
+struct trackDb *tdbList = loadTracks();
 
 cartWebStart(cart, database, "Extended DNA Case/Color");
 
 if (NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos"))))
     hgParseChromRange(database, pos, &seqName, &winStart, &winEnd);
 if (winEnd - winStart > 5000000)
     {
     printf("Please zoom in to 5 million bases or less to color the DNA");
     return;
     }
 
 printf("<H1>Extended DNA Case/Color Options</H1>\n");
 puts(
      "Use this page to highlight features in genomic DNA text. "
      "DNA covered by a particular track can be highlighted by "
@@ -5248,30 +5259,31 @@
 savePosInTextBox(seqName, winStart+1 - (revComp ? padding3 : padding5), winEnd + (revComp ? padding5 : padding3));
 printf(" Reverse complement ");
 cgiMakeCheckBox("hgSeq.revComp", revComp);
 printf("<BR>\n");
 printf("Letters per line ");
 cgiMakeIntVar("lineWidth", lineWidth, 3);
 printf(" Default case: ");
 cgiMakeRadioButton("hgSeq.casing", "upper", caseUpper);
 printf(" Upper ");
 cgiMakeRadioButton("hgSeq.casing", "lower", !caseUpper);
 printf(" Lower ");
 cgiMakeButton("Submit", "Submit");
 printf("<BR>\n");
 printf("<TABLE BORDER=1>\n");
 printf("<TR><TD>Track<BR>Name</TD><TD>Toggle<BR>Case</TD><TD>Under-<BR>line</TD><TD>Bold</TD><TD>Italic</TD><TD>Red</TD><TD>Green</TD><TD>Blue</TD></TR>\n");
+struct trackDb *tdb;
 for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
     {
     char *table = tdb->table;
     char *track = tdb->track;
     if ( sameString(USER_PSL_TRACK_NAME, table)
     ||   lookupCt(track) != NULL
     ||   (  tdbVisLimitedByAncestors(cart,tdb,TRUE,TRUE) != tvHide
          && forestHasUnderstandableTrack(database, tdb) ) )
         {
         char *visString = cartUsualString(cart, track, hStringFromTv(tdb->visibility));
          if (differentString(visString, "hide") && tdb->parent)
             {
             char *parentVisString = cartUsualString(cart, tdb->parentName,
                                         hStringFromTv(tdb->parent->visibility));
             if (sameString("hide", parentVisString))
@@ -5799,60 +5811,59 @@
     }
 return fbList;
 }
 
 void doGetDna3()
 /* Fetch DNA in extended color format */
 {
 struct dnaSeq *seq;
 struct cfm *cfm;
 int i;
 boolean isRc = cartUsualBoolean(cart, "hgSeq.revComp", FALSE);
 boolean defaultUpper = sameString(cartString(cart, "hgSeq.casing"), "upper");
 int winSize;
 int lineWidth = cartInt(cart, "lineWidth");
 struct rgbColor *colors;
-struct trackDb *tdbList = hTrackDb(database), *tdb;
-struct trackDb *ctdbList = tdbForCustomTracks();
-struct trackDb *utdbList = tdbForUserPsl();
+
+struct trackDb *tdbList = loadTracks();
+
 char *pos = NULL;
 Bits *uBits;	/* Underline bits. */
 Bits *iBits;    /* Italic bits. */
 Bits *bBits;    /* Bold bits. */
 
 if (NULL != (pos = stripCommas(cartOptionalString(cart, "getDnaPos"))))
     hgParseChromRange(database, pos, &seqName, &winStart, &winEnd);
 
 winSize = winEnd - winStart;
 uBits = bitAlloc(winSize);	/* Underline bits. */
 iBits = bitAlloc(winSize);	/* Italic bits. */
 bBits = bitAlloc(winSize);	/* Bold bits. */
 
-ctdbList = slCat(ctdbList, tdbList);
-tdbList = slCat(utdbList, ctdbList);
-
 cartWebStart(cart, database, "Extended DNA Output");
 printf("<PRE><TT>");
 printf(">%s:%d-%d %s\n", seqName, winStart+1, winEnd,
        (isRc ? "(reverse complement)" : ""));
 seq = hDnaFromSeq(database, seqName, winStart, winEnd, dnaLower);
 if (isRc)
     reverseComplement(seq->dna, seq->size);
 if (defaultUpper)
     touppers(seq->dna);
 
 AllocArray(colors, winSize);
+
+struct trackDb* tdb;
 for (tdb = tdbList; tdb != NULL; tdb = tdb->next)
     {
     char *track = tdb->track;
     char *table = tdb->table;
     struct featureBits *fbList = NULL, *fb;
     struct customTrack *ct = lookupCt(track);
     if (sameString(USER_PSL_TRACK_NAME, table)
     ||  ct != NULL
     ||  (   tdbVisLimitedByAncestors(cart,tdb,TRUE,TRUE) != tvHide
         && forestHasUnderstandableTrack(database, tdb) ) )
         {
         char buf[256];
         int r,g,b;
         /* to save a LOT of time, don't fetch track features unless some
          * coloring/formatting has been specified for them. */