cfed2e78dcef652dc85360454f81d7558aa1b678 kate Thu Oct 27 18:05:04 2016 -0700 Implement config panel cart vars. Moved from .html mockup to C code. refs #17369 diff --git src/hg/hgGtexTrackSettings/hgGtexTrackSettings.c src/hg/hgGtexTrackSettings/hgGtexTrackSettings.c index bc47caa..6d4e87b 100644 --- src/hg/hgGtexTrackSettings/hgGtexTrackSettings.c +++ src/hg/hgGtexTrackSettings/hgGtexTrackSettings.c @@ -1,200 +1,428 @@ /* hgGtexTrackSettings: Configure GTEx track * * Copyright (C) 2016 The Regents of the University of California */ #include "common.h" +#include "trackDb.h" #include "cart.h" +#include "portable.h" +#include "gtexUi.h" + +/* TODO: prune */ #include "cartJson.h" #include "cheapcgi.h" #include "errCatch.h" #include "googleAnalytics.h" #include "hCommon.h" #include "hgConfig.h" #include "hdb.h" #include "htmshell.h" #include "hubConnect.h" #include "hui.h" #include "jsHelper.h" #include "jsonParse.h" #include "obscure.h" // for readInGulp -#include "regexHelper.h" -#include "suggest.h" -#include "trackHub.h" -#include "trix.h" #include "web.h" #include "gtexInfo.h" #include "gtexTissue.h" /* Global Variables */ struct cart *cart = NULL; /* CGI and other variables */ struct hash *oldVars = NULL; /* Old contents of cart before it was updated by CGI */ char *db = NULL; +char *version; /* GTEx release */ +struct trackDb *tdb = NULL; static void doCartJson() /* Perform UI commands to update the cart and/or retrieve cart vars & metadata. */ { struct cartJson *cj = cartJsonNew(cart); //e.g. cartJsonRegisterHandler(cj, "setTaxId", setTaxId); cartJsonExecute(cj); } static void doJsIncludes() /* Include JS libraries. From hgGateway (think about libifying) */ { //puts(""); //puts(""); //puts(""); puts(""); webIncludeResourceFile("jquery-ui.css"); jsIncludeFile("jquery-ui.js", NULL); jsIncludeFile("jquery.watermarkinput.js", NULL); jsIncludeFile("utils.js",NULL); } -static void printTrackDescription() +static void printTrackHeader() +/* Print top banner with track labels */ { -puts(""); -puts("
"); -puts("
Track Description
"); -puts("
" - "" - "" - //"" - "
"); -puts("
"); -struct sqlConnection *conn = sqlConnect(db); -if (conn == NULL) - errAbort("Can't connect to database %s\n", db); -char query[256]; -sqlSafef(query, sizeof(query), "select html from trackDb where tableName='gtexGene'"); -char *html = sqlQuickString(conn, query); -if (html != NULL) - { - puts("
"); - puts("
"); -puts(html); - } -sqlDisconnect(&conn); -puts("
"); -puts(""); +char *assembly = stringBetween("(", ")", hFreezeFromDb(db)); + +puts( +"\n" +"
\n" +"
\n" +); + +printf( +" \n" +" %s Track\n" +" %s\n" +" \n" +"       %s    \n" +, tdb->shortLabel, assembly, tdb->longLabel); + +puts( +" " +" " +"
" +"
" +"
" +"
GO
" +" " +"
" +"
" +"
" +); } -static void printTissueTable(char *version) +static void printTissueTable() /* Output HTML with tissue labels and colors, in 2 columns, to fit next to body map */ { struct gtexTissue *tis, *tissues = gtexGetTissues(version); struct gtexTissue **tisTable = NULL; int count = slCount(tissues); AllocArray(tisTable, count); int i=0, col=0; int cols = 2; int last = count/2 + 1; +puts( + " " + "
" + "
Tissues
" + "
" + " Click label below or in Body Map to set or clear a tissue" + "
" + "
" + "
set all
" + "
clear all
" + "
" + "
" + ); + puts(""); puts(""); for (tis = tissues; tis != NULL; tis = tis->next) { if (tis->id < last) i = tis->id * 2; else i = (tis->id - last) * 2 + 1; tisTable[i] = tis; } for (i=0; i" "", tis->color, tis->name, tis->description); col++; if (col > cols-1) { puts("\n"); col = 0; } } puts("\n"); puts("
%s
"); } -static void doMainPage() -/* Send HTML with javascript to bootstrap the user interface. */ +static void printBodyMap() { -// Start web page with new banner -char *genome = NULL, *clade = NULL; -//getDbGenomeClade(cart, &db, &genome, &clade, oldVars); +puts( +" " +" " +" Body Map illustration not found" +" " +); +} -/* hardcode for now -- later, check for hg19 or hg38 */ +static void printVisSelect() +{ +enum trackVisibility vis = tdb->visibility; +vis = hTvFromString(cartUsualString(cart, tdb->track, hStringFromTv(vis))); +boolean canPack = TRUE; +hTvDropDownClassVisOnlyAndExtra(tdb->track, vis, canPack, "gbSelect normalText visDD", + trackDbSetting(tdb, "onlyVisibility"), NULL); +} -db = "hg19"; -genome = "human"; -clade = "mammal"; +static void printConfigPanel() +/* Controls for track configuration (except for tissues) */ +{ +char cartVar[1024]; +char buf[512]; -// char *chromosome = cartUsualString(cart, "c", hDefaultChrom(database)); -//char *track = cartString(cart, "g"); +char *track = tdb->track; + +puts( +" \n" + +/* Blue section header and track vis dropdown */ +"
\n" +"
Configuration
\n" +"
\n" +); +printVisSelect(); +puts( +"
\n" +); +puts( +"
\n" +); + +/* First row of config controls */ +puts( +" \n" +"
\n" + +/* Gene labels */ +"
\n" +"Label:  " +); +char *geneLabel = cartUsualStringClosestToHome(cart, tdb, isNameAtParentLevel(tdb, track), + GTEX_LABEL, GTEX_LABEL_DEFAULT); +safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_LABEL); +cgiMakeRadioButton(cartVar, GTEX_LABEL_SYMBOL , sameString(GTEX_LABEL_SYMBOL, geneLabel)); +printf("%s ", "gene symbol"); +cgiMakeRadioButton(cartVar, GTEX_LABEL_ACCESSION, sameString(GTEX_LABEL_ACCESSION, geneLabel)); +printf("%s ", "accession"); +cgiMakeRadioButton(cartVar, GTEX_LABEL_BOTH, sameString(GTEX_LABEL_BOTH, geneLabel)); +printf("%s ", "both"); +puts( +"
\n" + +/* Show exons in gene model */ +"
\n" +); +puts("Show GTEx gene model\n"); +safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_SHOW_EXONS); +boolean showExons = cartCgiUsualBoolean(cart, cartVar, GTEX_SHOW_EXONS_DEFAULT); +cgiMakeCheckBox(cartVar, showExons); +puts( +"
\n" +); +puts( +"
\n" +); + +/* Row 2 */ +puts( +" \n" +"
\n" +); + +/* Log transform. When selected, the next control (view limits max) is disabled */ +puts( +"
\n" +); +puts("Log10 transform:\n"); +safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_LOG_TRANSFORM); +boolean isLogTransform = cartCgiUsualBoolean(cart, cartVar, GTEX_LOG_TRANSFORM_DEFAULT); +safef(buf, sizeof buf, "onchange='gtexTransformChanged(\"%s\")'", track); +cgiMakeCheckBoxJS(cartVar, isLogTransform, buf); +puts( +"
\n" +); +/* Viewing limits max. This control is disabled if log transform is selected */ +// construct class so JS can toggle +puts( +"
\n" +); +safef(buf, sizeof buf, "%sViewLimitsMaxLabel %s", track, isLogTransform ? "disabled" : ""); +printf("View limits maximum:\n", buf); +safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_MAX_LIMIT); +int viewMax = cartCgiUsualInt(cart, cartVar, GTEX_MAX_LIMIT_DEFAULT); +cgiMakeIntVarWithExtra(cartVar, viewMax, 4, isLogTransform ? "disabled" : ""); +char *version = gtexVersion(tdb->table); +printf(" RPKM (range 0-%d)\n", buf, round(gtexMaxMedianScore(version))); +puts( +"
\n" +); +puts( +"
\n" +); + +/* Row 3 */ +puts( +" \n" +"
\n" +); +/* Filter on coding genes */ +puts( +"
\n" +); +puts("Limit to protein coding genes:\n"); +safef(cartVar, sizeof(cartVar), "%s.%s", track, GTEX_CODING_GENE_FILTER); +boolean isCodingOnly = cartCgiUsualBoolean(cart, cartVar, GTEX_CODING_GENE_FILTER_DEFAULT); +cgiMakeCheckBox(cartVar, isCodingOnly); +puts( +"
\n" +); + +/* Filter on score */ +puts( +"
\n" +); +puts("Limit to genes scored at or above:\n"); +puts( +" \n" +" (range 0-1000)\n" +); +puts( +"
\n" +); +puts( +"
\n" +); +puts( +" \n" +); +} + +static void printTrackConfig() +/* Print track configuration panels, including Body Map. +The layout is 2-column. Left column is body map SVG. +Right column has a top panel for configuration settings (non-tissue), +and a lower panel with a tissue selection list. +*/ +{ +puts( +"
\n" +); + +// TODO: remove bodyMap id here +puts( +"
\n" +); +printBodyMap(); +puts( +"
\n" +); +puts( +"
\n" +); +printConfigPanel(); +printTissueTable(); +puts( +"
\n" +); +puts( +"
\n" +); +} + +static void printTrackDescription() +{ +puts(""); +puts("
"); +puts("
Track Description
"); +puts("
" + "" + "" + //"" + "
"); +puts("
"); +if (tdb->html != NULL) + { + puts("
"); + puts("
"); +puts(tdb->html); + } +puts("
"); +puts(""); +} + +static void doMainPage() +/* Send HTML with javascript to bootstrap the user interface. */ +{ +// Start web page with new banner webStartJWestNoBanner(cart, db, "Genome Browser GTEx Track Settings"); puts(""); puts(""); -// The initial visible page elements are hgGtexTrackSettings.html, -// which is transformed into a quoted .h -// file containing a string constant that we #include and print here (see makefile). -puts( -#include "hgGtexTrackSettings.html.h" -); +char *genome = NULL, *clade = NULL; +// char *chromosome = cartUsualString(cart, "c", hDefaultChrom(database)); +//char *track = cartString(cart, "g"); +getDbGenomeClade(cart, &db, &genome, &clade, oldVars); -//struct tdb *tdbList = NULL; -//struct trackDb *tdb = tdbForTrack(db, track, &tdbList); -//printTissueTable(gtexGetVersion(tdb->table)); +// Check if this is an assembly with GTEx track +struct sqlConnection *conn = sqlConnect(db); +if (conn == NULL) + errAbort("Can't connect to database %s\n", db); char *table = "gtexGene"; +version = gtexVersion(table); -printTissueTable(gtexVersion(table)); -puts(""); +// TODO: use hdb, hTrackDbList to get table names of trackDb, +tdb = trackDbLoadWhere(conn, "trackDb", "tableName = 'gtexGene'"); +sqlDisconnect(&conn); +if (!tdb) + errAbort("No GTEx track found in database %s\n", db); +puts( +"
\n" +); +printTrackHeader(); +printTrackConfig(); printTrackDescription(); puts("
"); // end panel, section and body layout container // Track description // JS libraries doJsIncludes(); // Main JS puts(""); webIncludeFile("inc/jWestFooter.html"); webEndJWest(); } void doMiddle(struct cart *theCart) /* Display the main page or execute a command and update the page */ { cart = theCart; if (cgiOptionalString(CARTJSON_COMMAND)) doCartJson(); else doMainPage(); } int main(int argc, char *argv[]) /* Process CGI / command line. */ { /* Null terminated list of CGI Variables we don't want to save * permanently. */ -char *excludeVars[] = {CARTJSON_COMMAND, NULL}; +/* TODO: check these */ +char *excludeVars[] = { "submit", "Submit", "g", NULL, "ajax", NULL,}; +//char *excludeVars[] = {CARTJSON_COMMAND, NULL}; +long enteredMainTime = clock1000(); cgiSpoof(&argc, argv); oldVars = hashNew(10); cartEmptyShellNoContent(doMiddle, hUserCookie(), excludeVars, oldVars); +cgiExitTime("hgGtexTrackSettings", enteredMainTime); return 0; }