da33d70c10ddaae6c3290cb900d7d0cc2b6ee01b
hiram
Tue Mar 17 13:57:24 2026 -0700
allow calculation of GC percent on the fly with code help from claude refs #35958
diff --git src/hg/hgTrackUi/hgTrackUi.c src/hg/hgTrackUi/hgTrackUi.c
index 9138d99c494..278122e2f27 100644
--- src/hg/hgTrackUi/hgTrackUi.c
+++ src/hg/hgTrackUi/hgTrackUi.c
@@ -2271,30 +2271,48 @@
"}\n");
printf("",
oligoMatchVar, oligoMatchVar, 45, oligo);
puts("
Examples: TATAWAAR, AAAAA");
jsOnEventById("input", oligoMatchVar, "packTrack();");
puts("
Search strand: "); cgiMakeRadioButton(oligoMatchStrandVar, "both", sameString(strand, "both")); puts(" Both "); cgiMakeRadioButton(oligoMatchStrandVar, "forward", sameString(strand, "forward")); puts(" Forward (+) "); cgiMakeRadioButton(oligoMatchStrandVar, "reverse", sameString(strand, "reverse")); puts(" Reverse (-) "); } +static void gcOnFlyUi(struct trackDb *tdb) +/* UI for oligo match track */ +{ +char *winSize = cartUsualString(cart, gcOnFlyWindowSize, gcOnFlyDefaultSize); +puts("
GC Percent calculation window size: "); +jsInline( +"function fullTrack()\n" +"{\n" +"var box = jQuery('select[name$=gcOnFly]');\n" +"if (box.val()=='hide')\n" +" box.val('full');\n" +"}\n"); +printf("", + gcOnFlyWindowSize, gcOnFlySizeVar, 15, winSize); +jsOnEventById("input", gcOnFlySizeVar, "fullTrack();"); +puts("
UCSC standard window size is 5 bases. Adjust size as desired.
"); +} + void cutterUi(struct trackDb *tdb) /* UI for restriction enzyme track */ { char *enz = cartUsualString(cart, cutterVar, cutterDefault); puts("Filter display by enzymes (separate with commas):
");
cgiMakeTextVar(cutterVar, enz, 100);
}
void genericWiggleUi(struct trackDb *tdb, int optionNum )
/* put up UI for any standard wiggle track (a.k.a. sample track)*/
{
char options[7][256];
int thisHeightPer, thisLineGap;
float thisMinYRange, thisMaxYRange;
@@ -3314,30 +3332,32 @@
// add explicitly here only if track has another type (bed, chain).
// For crossSpeciesCfgUi, the
// default for chrom coloring is "on", unless track setting
// colorChromDefault is set to "off"
crossSpeciesCfgUi(cart,tdb);
else if (sameString(track, "affyTranscriptome"))
affyTranscriptomeUi(tdb);
else if (sameString(track, WIKI_TRACK_TABLE))
wikiTrackUi(tdb);
else if (sameString(track, RULER_TRACK_NAME))
rulerUi(tdb);
else if (sameString(trackHubSkipHubName(track), "quickLiftChain"))
quickLiftUi(tdb);
else if (sameString(track, OLIGO_MATCH_TRACK_NAME))
oligoMatchUi(tdb);
+else if (sameString(track, GC_ON_FLY_TRACK_NAME))
+ gcOnFlyUi(tdb);
else if (sameString(track, CUTTERS_TRACK_NAME))
cutterUi(tdb);
else if(sameString(track, "affyTransfrags"))
affyTransfragUi(tdb);
else if (sameString(track, "gvPos"))
gvUi(tdb);
else if (sameString(track, "oreganno"))
oregannoUi(tdb);
else if (startsWith("retroposons", track))
retroposonsUi(tdb);
else if (sameString(track, "tfbsConsSites"))
tfbsConsSitesUi(tdb);
else if (sameString(track, "CGHBreastCancerUCSF"))
ucsfdemoUi(tdb);
else if (startsWith("hapmapSnps", track))
@@ -3981,30 +4001,41 @@
/* Create a trackDb entry for the wikiTrack.
It is not a real track, so doesn't appear in trackDb */
{
return trackDbForPseudoTrack(WIKI_TRACK_TABLE,
WIKI_TRACK_LABEL, WIKI_TRACK_LONGLABEL, tvFull, FALSE);
}
struct trackDb *trackDbForRuler()
/* Create a trackDb entry for the base position ruler.
It is not (yet?) a real track, so doesn't appear in trackDb */
{
return trackDbForPseudoTrack(RULER_TRACK_NAME,
RULER_TRACK_LABEL, RULER_TRACK_LONGLABEL, tvFull, FALSE);
}
+static struct trackDb *trackDbForGcOnFly()
+/* Create a trackDb entry for the GC on the fly pseudo-track. */
+{
+char longLabel[1024];
+safef(longLabel, sizeof(longLabel), "GC FLY Percent in %s-Base Windows", gcOnFlyWinSize(cart));
+struct trackDb *tdb = trackDbForPseudoTrack(GC_ON_FLY_TRACK_NAME,
+ GC_ON_FLY_TRACK_LABEL, longLabel, tvFull, TRUE);
+tdb->canPack = 0;
+return tdb;
+}
+
struct trackDb *trackDbForOligoMatch()
/* Create a trackDb entry for the oligo matcher pseudo-track. */
{
return trackDbForPseudoTrack(OLIGO_MATCH_TRACK_NAME,
OLIGO_MATCH_TRACK_LABEL, OLIGO_MATCH_TRACK_LONGLABEL, tvHide, TRUE);
}
static char *handleDupOp(char *track, struct hash *trackHash)
/* Handle the duplication operation in the URL if any. Return dupe name if
* a dupe has happened. The trackHash is keyed by track name and has
* struct trackDb values. */
{
char *newTrack = NULL;
/* Handle duplicate, and possible in the future other operations on tracks. */
@@ -4094,30 +4125,32 @@
dupTdb = NULL; /* We use it! */
}
}
if (dupTdb != NULL)
slAddHead(&tdbList, dupTdb);
}
}
if (sameWord(track, WIKI_TRACK_TABLE))
tdb = trackDbForWikiTrack();
else if (sameWord(track, RULER_TRACK_NAME))
/* special handling -- it's not a full-fledged track */
tdb = trackDbForRuler();
else if (sameWord(track, OLIGO_MATCH_TRACK_NAME))
tdb = trackDbForOligoMatch();
+else if (sameWord(track, GC_ON_FLY_TRACK_NAME))
+ tdb = trackDbForGcOnFly(cart);
else if (sameWord(track, CUTTERS_TRACK_NAME))
tdb = trackDbForPseudoTrack(CUTTERS_TRACK_NAME, CUTTERS_TRACK_LABEL, CUTTERS_TRACK_LONGLABEL, tvHide, TRUE);
else if (isCustomTrack(track))
{
ctList = customTracksParseCart(database, cart, NULL, NULL);
for (ct = ctList; ct != NULL; ct = ct->next)
{
if (sameString(track, ct->tdb->track))
{
tdb = ct->tdb;
break;
}
}
}
else if (isHubTrack(track))