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/hgc/hgc.c src/hg/hgc/hgc.c
index 1fdbec2d209..fafdfa1af60 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -24163,30 +24163,65 @@
static void doOligoMatch(char *item)
/* Print info about oligo match. */
{
char *oligo = cartUsualString(cart,
oligoMatchVar, cloneString(oligoMatchDefault));
touppers(oligo);
cartWebStart(cart, database, "Perfect Matches to Short Sequence");
printf("Sequence: %s
\n", oligo);
printf("Chromosome: %s
\n", seqName);
printf("Start: %s
\n", item+1);
printf("Strand: %c
\n", item[0]);
webIncludeHelpFile(OLIGO_MATCH_TRACK_NAME, TRUE);
}
+static void doGcOnFly(void)
+/* Display GC percent info for visible window, computed on the fly from sequence.
+ * No tdb or bigWig file needed - this is a synthetic track with no database table. */
+{
+char *winSizeStr = cartUsualString(cart, gcOnFlyWindowSize, gcOnFlyDefaultSize);
+int span = atoi(winSizeStr);
+char num1Buf[64], num2Buf[64];
+
+cartWebStart(cart, database, "GC Percent On the Fly");
+sprintLongWithCommas(num1Buf, BASE_1(winStart));
+sprintLongWithCommas(num2Buf, winEnd);
+printf("Position: %s:%s-%s
\n", seqName, num1Buf, num2Buf);
+sprintLongWithCommas(num1Buf, winEnd - winStart);
+printf("Total bases in view: %s
\n", num1Buf);
+printf("Window size for GC calculation: %d bases
\n", span);
+
+struct dnaSeq *seq = hChromSeq(database, seqName, winStart, winEnd);
+if (seq != NULL)
+ {
+ int gcCount = 0, validBases = 0;
+ int i;
+ for (i = 0; i < seq->size; i++)
+ {
+ char b = seq->dna[i];
+ if (b == 'g' || b == 'c') { gcCount++; validBases++; }
+ else if (b != 'n') validBases++;
+ }
+ if (validBases > 0)
+ printf("GC percent in view: %.3f%%
\n",
+ 100.0 * gcCount / validBases);
+ dnaSeqFree(&seq);
+ }
+webIncludeHelpFile(GC_ON_FLY_TRACK_NAME, TRUE);
+}
+
struct slName *cutterIsoligamers(struct cutter *myEnzyme)
/* Find enzymes with same cut site. */
{
struct sqlConnection *conn;
struct cutter *cutters = NULL;
struct slName *ret = NULL;
conn = hAllocConn("hgFixed");
char query[1024];
sqlSafef(query, sizeof query, "select * from cutters");
cutters = cutterLoadByQuery(conn, query);
ret = findIsoligamers(myEnzyme, cutters);
hFreeConn(&conn);
cutterFreeList(&cutters);
return ret;
@@ -27149,30 +27184,32 @@
else if (sameWord(table, "affyU95")
|| sameWord(table, "affyU133")
|| sameWord(table, "affyU74")
|| sameWord(table, "affyRAE230")
|| sameWord(table, "affyZebrafish")
|| sameWord(table, "affyGnf1h")
|| sameWord(table, "affyMOE430v2")
|| sameWord(table, "affyGnf1m") )
{
doAffy(tdb, item, NULL);
}
else if (sameWord(table, WIKI_TRACK_TABLE))
doWikiTrack(item, seqName, winStart, winEnd);
else if (sameWord(table, OLIGO_MATCH_TRACK_NAME))
doOligoMatch(item);
+else if (sameWord(table, GC_ON_FLY_TRACK_NAME))
+ doGcOnFly();
else if (sameWord(table, "refFullAli"))
{
doTSS(tdb, item);
}
else if (sameWord(table, "rikenMrna"))
{
doRikenRna(tdb, item);
}
else if (sameWord(table, "cgapSage"))
{
doCgapSage(tdb, item);
}
else if (sameWord(table, "ctgPos") || sameWord(table, "ctgPos2"))
{
doHgContig(tdb, item);