5a63b70b7e8405a187c8fba71c557cca655e0424
kate
  Wed Aug 24 12:17:38 2016 -0700
Add config option to display ENS geneId.  For synergy with new GTEx gene sorter column. refs #17288

diff --git src/hg/hgTracks/gtexTracks.c src/hg/hgTracks/gtexTracks.c
index 1bd5a34..5a9b71b 100644
--- src/hg/hgTracks/gtexTracks.c
+++ src/hg/hgTracks/gtexTracks.c
@@ -2,55 +2,76 @@
 
 /* Copyright (C) 2015 The Regents of the University of California 
  * See README in this or parent directory for licensing information. */
 
 #include "common.h"
 #include "hgTracks.h"
 #include "hvGfx.h"
 #include "rainbow.h"
 #include "gtexInfo.h"
 #include "gtexGeneBed.h"
 #include "gtexTissue.h"
 #include "gtexTissueData.h"
 #include "gtexUi.h"
 #include "spaceSaver.h"
 
+enum geneLabelStyle
+    {
+    LABEL_GENE_SYMBOL = 0,
+    LABEL_GENE_ACCESSION = 1,
+    LABEL_BOTH = 2
+    };
+
+static enum geneLabelStyle getLabelStyle(char *cartVar)
+/* Get enum corresponding to cart var */
+{
+    if (sameString(GTEX_LABEL_SYMBOL, cartVar))
+        return LABEL_GENE_SYMBOL;
+    if (sameString(GTEX_LABEL_ACCESSION, cartVar))
+        return LABEL_GENE_ACCESSION;
+    if (sameString(GTEX_LABEL_BOTH, cartVar))
+        return LABEL_BOTH;
+    return LABEL_GENE_SYMBOL;
+}
+
 struct gtexGeneExtras 
 /* Track info */
     {
     char *version;              /* Suffix to table name, e.g. 'V6' */
     boolean codingOnly;         /* User filter to limit display to coding genes */
     boolean showExons;          /* Show gene model exons */
     boolean noWhiteout;         /* Suppress whiteout of graph background (allow highlight, blue lines) */
+    enum geneLabelStyle labelStyle;  /* Show gene symbol, accession, or both */ 
     double maxMedian;           /* Maximum median rpkm for all tissues */
     boolean isComparison;       /* Comparison of two sample sets (e.g. male/female). */
     boolean isDifference;       /* True if comparison is shown as a single difference graph. 
                                    False if displayed as two graphs, one oriented downward */
     char *graphType;            /* Additional info about graph (e.g. type of comparison graph */
     struct rgbColor *colors;    /* Color palette for tissues */
     boolean doLogTransform;     /* Log10(x+1) */
     struct gtexTissue *tissues; /* Cache tissue names, descriptions */
     struct hash *tissueFilter;  /* For filter. NULL out excluded tissues */
     };
 
 struct gtexGeneInfo
 /* GTEx gene model, names, and expression medians */
     {
     struct gtexGeneInfo *next;  /* Next in singly linked list */
     struct gtexGeneBed *geneBed;/* Gene name, id, type, exp count and medians 
                                         from BED table */
     struct genePred *geneModel; /* Gene structure from model table */
+    char *label;                /* Name, accession, or both */
     char *description;          /* Gene description */
     double *medians1;            /* Computed medians */
     double *medians2;            /* Computed medians for comparison (inverse) graph */
     int height;                  /* Item height in pixels */
     };
 
 
 #define MAX_DESC  200
 /***********************************************/
 /* Color gene models using GENCODE conventions */
 
 static struct rgbColor codingColor = {12, 12, 120}; // #0C0C78
 static struct rgbColor nonCodingColor = {0, 100, 0}; // #006400
 static struct rgbColor pseudoColor = {255,51,255}; // #FF33FF
 static struct rgbColor problemColor = {254, 0, 0}; // #FE0000
@@ -388,30 +409,32 @@
 char *samples = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, 
                                                 GTEX_SAMPLES, GTEX_SAMPLES_DEFAULT);
 extras->graphType = cloneString(samples);
 if (sameString(samples, GTEX_SAMPLES_COMPARE_SEX))
     extras->isComparison = TRUE;
 char *comparison = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, GTEX_COMPARISON_DISPLAY,
                         GTEX_COMPARISON_DEFAULT);
 extras->isDifference = sameString(comparison, GTEX_COMPARISON_DIFF) ? TRUE : FALSE;
 extras->maxMedian = gtexMaxMedianScore(extras->version);
 extras->codingOnly = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, GTEX_CODING_GENE_FILTER,
                                                         GTEX_CODING_GENE_FILTER_DEFAULT);
 extras->showExons = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, GTEX_SHOW_EXONS,
                                                         GTEX_SHOW_EXONS_DEFAULT);
 extras->noWhiteout = cartUsualBooleanClosestToHome(cart, tg->tdb, FALSE, GTEX_NO_WHITEOUT,
                                                         GTEX_NO_WHITEOUT_DEFAULT);
+extras->labelStyle = getLabelStyle(cartUsualStringClosestToHome(cart, tg->tdb, FALSE, GTEX_LABEL,
+                                                        GTEX_LABEL_DEFAULT));
 /* Get geneModels in range */
 char buf[256];
 char *modelTable = "gtexGeneModel";
 safef(buf, sizeof(buf), "%s%s", modelTable, extras->version ? extras->version: "");
 struct hash *modelHash = loadGeneModels(buf);
 
 /* Get geneBeds (names and all-sample tissue median scores) in range */
 char *filter = getScoreFilterClause(cart, tg->tdb, NULL);
 bedLoadItemWhere(tg, tg->table, filter, (ItemLoader)gtexGeneBedLoad);
 
 /* Create geneInfo items with BED and geneModels */
 struct gtexGeneInfo *geneInfo = NULL, *list = NULL;
 struct gtexGeneBed *geneBed = (struct gtexGeneBed *)tg->items;
 
 /* Load tissue colors: GTEx or rainbow */
@@ -433,61 +456,80 @@
 	extras->colors = getRainbow(&saturatedRainbowAtPos, expCount);
 	}
     }
 filterTissues(tg);
 
 while (geneBed != NULL)
     {
     if (extras->codingOnly && !gtexGeneIsCoding(geneBed))
         {
         // apologies for messy short-circuit
         geneBed = geneBed->next;
         continue;
         }
     AllocVar(geneInfo);
     geneInfo->geneBed = geneBed;
+    
+    // set label
+    if (extras->labelStyle == LABEL_GENE_SYMBOL)
+        geneInfo->label = geneBed->name;
+    else if (extras->labelStyle == LABEL_GENE_ACCESSION)
+        geneInfo->label = geneBed->geneId;
+    else if (extras->labelStyle == LABEL_BOTH)
+        {
+        char buf[256];
+        safef(buf, sizeof(buf), "%s/%s", geneBed->name, geneBed->geneId);
+        geneInfo->label = cloneString(buf);
+        }
+    else
+        geneInfo->label = "";
+
+    // get description
     geneInfo->geneModel = hashFindVal(modelHash, geneBed->geneId); // sometimes this is missing, hash returns NULL. do we check?
     // NOTE: Consider loading all gene descriptions to save queries
     char query[256];
     sqlSafef(query, sizeof(query),
             "select kgXref.description from kgXref where geneSymbol='%s'", geneBed->name);
     struct sqlConnection *conn = hAllocConn(database);
     char *desc = sqlQuickString(conn, query);
     hFreeConn(&conn);
     if (desc)
         {
         // hg38 known genes has extra detail about source; strip it
         char *fromDetail = strstrNoCase(desc, "(from");
         if (fromDetail)
             *fromDetail = 0;
         if (strlen(desc) > MAX_DESC)
             strcpy(desc+MAX_DESC, "...");
         // also strip 'homo sapiens' prefix
         #define SPECIES_PREFIX  "Homo sapiens "
         if (startsWith(SPECIES_PREFIX, desc))
             desc += strlen(SPECIES_PREFIX);
         geneInfo->description = desc;
         }
     else
         geneInfo->description = geneInfo->geneBed->name;
+
     slAddHead(&list, geneInfo);
     geneBed = geneBed->next;
     geneInfo->geneBed->next = NULL;
+
     if (extras->isComparison && (tg->visibility == tvFull || tg->visibility == tvPack))
         // compute medians based on configuration (comparisons, and later, filters)
         loadComputedMedians(geneInfo, extras);
     geneInfo->height = gtexGeneItemHeight(tg, geneInfo);
+
     }
 slReverse(&list);
 tg->items = list;
 }
 
 /***********************************************/
 /* Draw */
 
 /* Bargraph layouts for three window sizes */
 #define WIN_MAX_GRAPH 50000
 #define MAX_GRAPH_HEIGHT 175
 #define MAX_BAR_WIDTH 5
 #define MAX_GRAPH_PADDING 2
 
 #define WIN_MED_GRAPH 500000
@@ -1022,32 +1064,31 @@
     // map over label
     int itemHeight = geneInfo->height;
     mapBoxHc(hvg, geneStart, geneEnd, x1-labelWidth, y, labelWidth, itemHeight-3, 
                         tg->track, mapItemName, geneInfo->description);
     // map over gene model (extending to end of item)
     int geneModelHeight = gtexGeneModelHeight(extras);
     mapBoxHc(hvg, geneStart, geneEnd, x1, y+itemHeight-geneModelHeight-3, w, geneModelHeight,
                         tg->track, mapItemName, geneInfo->description);
     } 
 }
 
 static char *gtexGeneItemName(struct track *tg, void *item)
 /* Return gene name */
 {
 struct gtexGeneInfo *geneInfo = (struct gtexGeneInfo *)item;
-struct gtexGeneBed *geneBed = geneInfo->geneBed;
-return geneBed->name;
+return geneInfo->label;
 }
 
 static int gtexGeneHeight(void *item)
 {
 struct gtexGeneInfo *geneInfo = (struct gtexGeneInfo *)item;
 assert(geneInfo->height != 0);
 return geneInfo->height;
 }
 
 static int gtexGeneTotalHeight(struct track *tg, enum trackVisibility vis)
 /* Figure out total height of track. Set in track and also return it */
 {
 int height = 0;
 int lineHeight = 0;
 int heightPer = 0;