02f9444f186888d2da5d65d9db583ddf2d7b95ca jcasper Thu Oct 22 01:48:20 2020 -0700 Adding trackDb options to change defaults for hic tracks. Also made some of those settings case-insensitive. refs #26312 diff --git src/hg/lib/hicUi.c src/hg/lib/hicUi.c index d06f07f..485fa2e 100644 --- src/hg/lib/hicUi.c +++ src/hg/lib/hicUi.c @@ -1,97 +1,97 @@ /* hic track controls */ /* Copyright (C) 2019 The Regents of the University of California * See README in this or parent directory 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" 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[] = {"NONE", "VC", "VC_SQRT", "KR"}; -int i, sanityCheck = 0; -for (i=0; i<4; i++) - { - if (sameOk(selected, menu[i])) - sanityCheck = 1; - } -if (!sanityCheck) +int i; +char *result = menu[0]; +for (i=1; i<4; i++) { - selected = menu[0]; + if (sameWordOk(selected, menu[i])) + result = menu[i]; } -return selected; +return result; } void hicUiNormalizationDropDown(struct cart *cart, struct trackDb *tdb, struct hicMeta *meta) { char cartVar[1024]; char* selected = hicUiFetchNormalization(cart, tdb, meta); char *menu[] = {"NONE", "VC", "VC_SQRT", "KR"}; safef(cartVar, sizeof(cartVar), "%s.%s", tdb->track, HIC_NORMALIZATION); cgiMakeDropList(cartVar, menu, 4, selected); } void hicUiNormalizationMenu(struct cart *cart, struct trackDb *tdb, struct hicMeta *meta) /* Draw a menu to select the normalization method to use. */ { printf("Score normalization: "); hicUiNormalizationDropDown(cart, tdb, meta); } char *hicUiFetchResolution(struct cart *cart, struct trackDb *tdb, struct hicMeta *meta) /* Return the current resolution selection, or the default if none * has been selected. */ { char cartVar[1024]; safef(cartVar, sizeof(cartVar), "%s.%s", tdb->track, HIC_RESOLUTION); char *selected = cartNonemptyString(cart, cartVar); -int sanityCheck = sameOk(selected, "Auto"); +if (selected == NULL) + selected = trackDbSetting(tdb, HIC_TDB_RESOLUTION); int i; +char *result = "Auto"; for (i=0; inRes; i++) { if (sameOk(selected, meta->resolutions[i])) - sanityCheck = 1; + result = selected; } -if (!sanityCheck) - selected = "Auto"; -return selected; +return result; } int hicUiFetchResolutionAsInt(struct cart *cart, struct trackDb *tdb, struct hicMeta *meta, int windowSize) /* Return the current resolution selection as an integer. If there is no selection, or if "Auto" * has been selected, return the largest available value that still partitions the window into at * least 500 bins. */ { char *resolutionString = hicUiFetchResolution(cart, tdb, meta); int result; -if (sameOk(resolutionString, "Auto")) +if (sameWordOk(resolutionString, "Auto")) { int idealRes = windowSize/500; int autoRes = atoi(meta->resolutions[meta->nRes-1]); int smallestRes = autoRes; // in case the ideal resolution is smaller than anything available int i, success = 0; for (i=meta->nRes-1; i>= 0; i--) { int thisRes = atoi(meta->resolutions[i]); if (thisRes < smallestRes) smallestRes = thisRes; // not sure about the sort order of the list if (thisRes < idealRes && thisRes >= autoRes) { autoRes = thisRes; success = 1; } @@ -132,117 +132,144 @@ } void hicUiResolutionMenu(struct cart *cart, struct trackDb *tdb, struct hicMeta *meta) /* Draw a menu to select which binSize to use for fetching data */ { printf("Resolution: "); hicUiResolutionDropDown(cart, tdb, meta); } char *hicUiFetchDrawMode(struct cart *cart, struct trackDb *tdb) /* Return the current draw mode selection, or the default if none * has been selected. */ { char *selected = cartOptionalStringClosestToHome(cart, tdb, FALSE, HIC_DRAW_MODE); -if ( !sameOk(selected, HIC_DRAW_MODE_SQUARE) && - !sameOk(selected, HIC_DRAW_MODE_ARC) && - !sameOk(selected, HIC_DRAW_MODE_TRIANGLE) ) +if (selected == NULL) { - selected = HIC_DRAW_MODE_DEFAULT; + selected = trackDbSetting(tdb, HIC_TDB_DRAW_MODE); } -return selected; +char *result = HIC_DRAW_MODE_DEFAULT; +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; } 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("Draw mode: "); 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}; char* selected = hicUiFetchDrawMode(cart, tdb); cgiMakeDropList(cartVar, menu, 3, selected); } char *hicUiFetchDrawColor(struct cart *cart, struct trackDb *tdb) /* Retrieve the HTML hex code for the color to draw the * track values in (e.g., #00ffa1) */ { +// Color might have been specified in the cart, probably in #aabbcc format char* selected = cartOptionalStringClosestToHome(cart, tdb, FALSE, HIC_DRAW_COLOR); if (selected == NULL) - selected = HIC_DRAW_COLOR_DEFAULT; + // Or color might be in trackDb, probably in R,G,B format + selected = trackDbSettingClosestToHomeOrDefault(tdb, HIC_TDB_COLOR, HIC_DRAW_COLOR_DEFAULT); +const char *commaColorExpr = "^[0-9]+,[0-9]+,[0-9]+$"; +if (regexMatch(selected, commaColorExpr)) + { + // Parse a color in %d,%d,%d format and convert to something the html color tool can use. + // Don't want to use pre-parsed trackDb color values just in case string came from the cart instead + unsigned char r, g, b; + unsigned unifiedColor; + parseColor(selected, &r, &g, &b); + htmlColorFromRGB(&unifiedColor, r, g, b); + char *hexColor = htmlColorToCode(unifiedColor); + selected = hexColor; + } const char *colorExpr ="^#[0-9a-fA-F]{6}$"; if (!regexMatch(selected, colorExpr)) { selected = HIC_DRAW_COLOR_DEFAULT; } return selected; } char *hicUiFetchBgColor(struct cart *cart, struct trackDb *tdb) /* Retrieve the HTML hex code of the background color for the * track. This is the color associated with scores at or close to 0. */ { char* selected = cartOptionalStringClosestToHome(cart, tdb, FALSE, HIC_DRAW_BG_COLOR); if (selected == NULL) selected = HIC_DRAW_BG_COLOR_DEFAULT; const char *colorExpr ="^#[0-9a-fA-F]{6}$"; if (!regexMatch(selected, colorExpr)) { selected = HIC_DRAW_BG_COLOR_DEFAULT; } return selected; } double hicUiFetchMaxValue(struct cart *cart, struct trackDb *tdb) /* Retrieve the score value at which the draw color reaches its * its maximum intensity. Any scores above this value will * share that same draw color. */ { -return cartUsualDoubleClosestToHome(cart, tdb, FALSE, HIC_DRAW_MAX_VALUE, HIC_DRAW_MAX_VALUE_DEFAULT); +double defaultValue = HIC_DRAW_MAX_VALUE_DEFAULT; +char *tdbString = trackDbSetting(tdb, HIC_TDB_MAX_VALUE); +if (!isEmpty(tdbString)) + defaultValue = atof(tdbString); +return cartUsualDoubleClosestToHome(cart, tdb, FALSE, HIC_DRAW_MAX_VALUE, defaultValue); } void hicUiAddAutoScaleJS(struct cart *cart, char *track) /* Write out a bit of javascript to associate checking/unchecking the autoscale * checkbox with deactivating/activating (respectively) the maximum score * input. */ { struct dyString *new = dyStringNew(0); dyStringPrintf(new, "$('input[name=\"%s.%s\"]')[0].onclick = function() {", track, HIC_DRAW_AUTOSCALE); dyStringPrintf(new, "if (this.checked) {$('input[name=\"%s.%s\"]')[0].disabled = true; $('span#hicMaxText').css('color', 'gray');}", track, HIC_DRAW_MAX_VALUE); dyStringPrintf(new, "else {$('input[name=\"%s.%s\"]')[0].disabled = false; $('span#hicMaxText').css('color', '');} };\n", track, HIC_DRAW_MAX_VALUE); dyStringPrintf(new, "if ($('input[name=\"%s.%s\"]')[0].checked) {$('input[name=\"%s.%s\"]')[0].disabled = true; $('span#hicMaxText').css('color', 'gray');}\n", track, HIC_DRAW_AUTOSCALE, track, HIC_DRAW_MAX_VALUE); jsInline(dyStringContents(new)); dyStringFree(&new); } boolean hicUiFetchAutoScale(struct cart *cart, struct trackDb *tdb) /* Returns whether the track is configured to automatically scale its color range * depending on the scores present in the window, or if it should stick to a * gradient based on the user's selected maximum value. */ { -return cartUsualBooleanClosestToHome(cart, tdb, FALSE, HIC_DRAW_AUTOSCALE, TRUE); +boolean defaultVal = TRUE; +char *tdbSetting = trackDbSetting(tdb, HIC_TDB_AUTOSCALE); +if (tdbSetting != NULL) + defaultVal = trackDbSettingClosestToHomeOn(tdb, HIC_TDB_AUTOSCALE); +return cartUsualBooleanClosestToHome(cart, tdb, FALSE, HIC_DRAW_AUTOSCALE, defaultVal); } void hicUiColorMenu(struct cart *cart, struct trackDb *tdb) /* Draw the menu inputs associated with selecting draw colors for the track. */ { char cartVar[1024]; printf("Color: "); safef(cartVar, sizeof(cartVar), "%s.%s", tdb->track, HIC_DRAW_COLOR); char* selected = hicUiFetchDrawColor(cart, tdb); printf("\n", cartVar, selected); // Leaving out background color options for now. We'll see if this option is requested. /* printf("Background color: ");