34f380bfb0b4003a23fe2e00be6bdac6af326cda
jcasper
  Mon Dec 15 15:20:13 2025 -0800
Adding hicArcLimit and hicArcLimitEnabled settings to let people prevent excessive
arc counts from overwhelming a Hi-C display with data, refs #36774

diff --git src/hg/lib/hicUi.c src/hg/lib/hicUi.c
index 1df683007a3..76f6b4433e0 100644
--- src/hg/lib/hicUi.c
+++ src/hg/lib/hicUi.c
@@ -3,30 +3,82 @@
 /* Copyright (C) 2019 The Regents of the University of California 
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 
 #include "cheapcgi.h"
 #include "cart.h"
 #include "hui.h"
 #include "web.h"
 #include "trackDb.h"
 #include "hicUi.h"
 #include "cStraw.h"
 #include "regexHelper.h"
 #include "obscure.h"
 #include "htmshell.h"
 #include "htmlColor.h"
 
+boolean hicUiArcLimitEnabled(struct cart *cart, struct trackDb *tdb)
+/* Returns true if the checkbox for limiting the number of displayed arcs is checked */
+{
+//return cartUsualBooleanClosestToHome(cart, tdb, FALSE, HIC_ARC_LIMIT_CHECKBOX, FALSE);
+return cartOrTdbBoolean(cart, tdb, HIC_ARC_LIMIT_CHECKBOX, FALSE);
+}
+
+int hicUiGetArcLimit(struct cart *cart, struct trackDb *tdb)
+/* Returns the currently configured limit on the number of arcs drawn in arc mode.
+ * Defaults to 5000.
+ */
+{
+//int arcLimit = cartUsualIntClosestToHome(cart, tdb, FALSE, HIC_ARC_LIMIT, 5000);
+int arcLimit = cartOrTdbInt(cart, tdb, HIC_ARC_LIMIT, 5000);
+return arcLimit;
+}
+
+void hicUiAddArcLimitJS(struct cart *cart, char *track)
+/* Write out a bit of javascript to associate checking/unchecking the arc count
+ * limit checkbox with deactivating/activating (respectively) the text
+ * input.  */
+{
+struct dyString *new = dyStringNew(0);
+dyStringPrintf(new, "$('input[name=\"%s.%s\"]')[0].onclick = function() {", track, HIC_ARC_LIMIT_CHECKBOX);
+dyStringPrintf(new, "if (this.checked) {$('input[name=\"%s.%s\"]')[0].disabled = false; $('span#hicArcLimitText').css('color', '');}", track, HIC_ARC_LIMIT);
+dyStringPrintf(new, "else {$('input[name=\"%s.%s\"]')[0].disabled = true; $('span#hicArcLimitText').css('color', 'gray');} };\n", track, HIC_ARC_LIMIT);
+dyStringPrintf(new, "if (!$('input[name=\"%s.%s\"]')[0].checked) {$('input[name=\"%s.%s\"]')[0].disabled = true; $('span#hicArcLimitText').css('color', 'gray');}\n",
+        track, HIC_ARC_LIMIT_CHECKBOX, track, HIC_ARC_LIMIT);
+jsInline(dyStringContents(new));
+dyStringFree(&new);
+}
+
+void hicUiArcLimitSection(struct cart *cart, struct trackDb *tdb)
+/* Draw the menu inputs associated with selecting whether the track should automatically
+ * scale its color gradient based on the scores present in the view window, or whether it
+ * should stick to a gradient based on a user-selected maximum score. */
+{
+printf("\n");
+char cartVar[1024];
+safef(cartVar, sizeof(cartVar), "%s.%s", tdb->track, HIC_ARC_LIMIT_CHECKBOX);
+boolean arcLimitChecked = hicUiArcLimitEnabled(cart, tdb);
+cgiMakeCheckBox(cartVar, arcLimitChecked);
+int currentLimit = hicUiGetArcLimit(cart, tdb);
+safef(cartVar, sizeof(cartVar), "%s.%s", tdb->track, HIC_ARC_LIMIT);
+printf("&nbsp;&nbsp;<span id='hicArcLimitText'><b>Limit arcs to the</b> ");
+cgiMakeIntVar(cartVar, currentLimit, 6);
+printf("<b> strongest interactions</b> </span>\n");
+
+hicUiAddArcLimitJS(cart, tdb->track);
+}
+
+
 char *hicUiFetchNormalization(struct cart *cart, struct trackDb *tdb, struct hicMeta *meta)
 /* Return the current normalization selection, or the default if none
  * has been selected.  Right now this is a hard-coded set specifically for
  * .hic files, but in the future this list might be dynamically determined by
  * the contents and format of the Hi-C file. */
 {
 char cartVar[1024];
 safef(cartVar, sizeof(cartVar), "%s.%s", tdb->track, HIC_NORMALIZATION);
 char *selected = cartNonemptyString(cart, cartVar);
 if (selected == NULL)
     selected = trackDbSetting(tdb, HIC_TDB_NORMALIZATION);
 char **menu = meta->normOptions;
 int i;
 char *result = menu[0];
 for (i=1; i<meta->nNormOptions; i++)
@@ -152,31 +204,32 @@
 if (sameWordOk(selected, HIC_DRAW_MODE_SQUARE))
     result = HIC_DRAW_MODE_SQUARE;
 else if (sameWordOk(selected, HIC_DRAW_MODE_ARC))
     result = HIC_DRAW_MODE_ARC;
 else if (sameWordOk(selected, HIC_DRAW_MODE_TRIANGLE))
     result = HIC_DRAW_MODE_TRIANGLE;
 return result;
 }
 
 boolean hicUiFetchInverted(struct cart *cart, struct trackDb *tdb)
 /* Check if the user has set this track to draw in inverted mode.
  * Ideally this would also be available via a trackDb setting, but
  * this is the first pass at this feature. */
 {
 boolean defaultVal = FALSE;
-return cartUsualBooleanClosestToHome(cart, tdb, FALSE, HIC_DRAW_INVERTED, defaultVal);
+//return cartUsualBooleanClosestToHome(cart, tdb, FALSE, HIC_DRAW_INVERTED, defaultVal);
+return cartOrTdbBoolean(cart, tdb, HIC_DRAW_INVERTED, defaultVal);
 }
 
 
 void hicUiDrawMenu(struct cart *cart, struct trackDb *tdb)
 /* Draw the list of draw mode options for Hi-C tracks.  Square is the
  * standard square-shaped heatmap with the chromosome position axis on
  * a diagonal from top left to bottom right.  Triangle is the top half
  * of that square, after rotating it 45 degrees to have the position
  * axis lie horizontally.  Arc draws arcs between related positions,
  * but skips over self-relations. */
 {
 char cartVar[1024];
 printf("<b>Draw mode:</b> ");
 safef(cartVar, sizeof(cartVar), "%s.%s", tdb->track, HIC_DRAW_MODE);
 char *menu[] = {HIC_DRAW_MODE_SQUARE, HIC_DRAW_MODE_TRIANGLE, HIC_DRAW_MODE_ARC};
@@ -394,30 +447,32 @@
 printf("Items are drawn in shades of the chosen color depending on score - scores above the "
         "chosen maximum are drawn at full intensity.</p><p>\n");
 hicUiNormalizationMenu(cart, tdb, trackMeta);
 puts("&nbsp;&nbsp;");
 hicUiMaxOptionsMenu(cart, tdb, FALSE);
 
 puts("</p><p>");
 hicUiDrawMenu(cart, tdb);
 puts("&nbsp;&nbsp;");
 hicUiResolutionMenu(cart, tdb, trackMeta);
 puts("&nbsp;&nbsp;");
 hicUiColorMenu(cart, tdb);
 puts("</p><p>\n");
 hicUiMinMaxRangeMenu(cart, tdb);
 puts("</p><p>\n");
+hicUiArcLimitSection(cart, tdb);
+puts("</p><p>\n");
 hicUiFileDetails(trackMeta);
 cfgEndBox(boxed);
 }
 
 void hicCfgUiComposite(struct cart *cart, struct trackDb *tdb, char *track,
                         char *title, boolean boxed)
 /* Draw the (empty) list of track configuration options for a composite of Hi-C tracks */
 {
 boxed = cfgBeginBoxAndTitle(tdb, boxed, title);
 
 puts("<p>");
 printf("Items are drawn in shades of the chosen color depending on score - scores above the "
         "chosen maximum are drawn at full intensity.</p><p>\n");
 hicUiMaxOptionsMenu(cart, tdb, TRUE);
 puts("</p><p>");