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))