89ab8ae5fb747465c8f9c218c8556750033e2061
jcasper
  Wed May 16 20:02:03 2018 -0700
DECIPHER CNVs track handles new format, also release of SNVs track, refs #21104

diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index 1d376ae..0fb88e6 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -6588,140 +6588,234 @@
 
 w = x2-x1;
 if (w < 1)
     w = 1;
 hvGfxBox(hvg, x1, y, w, heightPer, color);
 
 if (vis == tvFull)
     {
     // New text for label in full mode:
     char *sDiseaseClasses = gadDiseaseClassList(bed->name);
     int textWidth = mgFontStringWidth(font, sDiseaseClasses);
     hvGfxTextRight(hvg, x1-textWidth-2, y, textWidth, heightPer, MG_BLACK, font, sDiseaseClasses);
     }
 }
 
-static char *decipherPhenotypeList(char *name)
-/* Return list of diseases associated with a DECIPHER entry */
+static char *decipherCnvsPhenotypeList(char *name)
+/* Return list of diseases associated with a DECIPHER CNVs entry */
 {
 char query[256];
 static char list[4096];
 struct sqlConnection *conn = hAllocConn(database);
 if (sqlFieldIndex(conn, "decipherRaw", "phenotypes") >= 0)
     {
     list[0] = '\0';
     sqlSafef(query, sizeof(query),
         "select phenotypes from decipherRaw where id='%s'", name);
     struct sqlResult *sr = sqlMustGetResult(conn, query);
     char **row = sqlNextRow(sr);
     if ((row != NULL) && strlen(row[0]) >= 1)
         {
         char *prettyResult = replaceChars(row[0], "|", "; ");
         safecpy(list, sizeof(list), prettyResult);
         // freeMem(prettyResult);
         }
     sqlFreeResult(&sr);
     }
 else
     {
     sqlSafef(query, sizeof(query),
         "select distinct phenotype from decipherRaw where id='%s' order by phenotype", name);
     hFreeConn(&conn);
     return collapseRowsFromQuery(query, "; ", 20);
     }
 hFreeConn(&conn);
 return list;
 }
 
-void decipherLoad(struct track *tg)
-/* Load DECIPHER items with extra labels from decipherPhenotypeList. */
+void decipherCnvsLoad(struct track *tg)
+/* Load DECIPHER CNVs items with extra labels from decipherPhenotypeList. */
 {
-bedPlusLabelLoad(tg, decipherPhenotypeList);
+bedPlusLabelLoad(tg, decipherCnvsPhenotypeList);
 }
 
-Color decipherColor(struct track *tg, void *item, struct hvGfx *hvg)
-/* Return color to draw DECIPHER entry */
+Color decipherCnvsColor(struct track *tg, void *item, struct hvGfx *hvg)
+/* Return color to draw DECIPHER CNVs entry */
 {
 struct bed *bed = item;
 int col = tg->ixColor;
 struct sqlConnection *conn = hAllocConn(database);
 struct sqlResult *sr;
 char **row;
 char query[256];
 char cond_str[256];
 char *decipherId = NULL;
 
 /* So far, we can just remove "chr" from UCSC chrom names to get DECIPHER names */
 char *decipherChrom = bed->chrom;
 if (startsWithNoCase("chr", bed->chrom))
     decipherChrom += 3;
 
 /* color scheme:
 	RED:	If the entry is a deletion (mean ratio < 0)
 	BLUE:	If the entry is a duplication (mean ratio > 0)
+	GREY:	If the entry was not provided with a mean ratio value (or it's 0)
 */
 sqlSafefFrag(cond_str, sizeof(cond_str),"name='%s' ", bed->name);
 decipherId = sqlGetField(database, "decipher", "name", cond_str);
 if (decipherId != NULL)
     {
     if (hTableExists(database, "decipherRaw"))
         {
         sqlSafef(query, sizeof(query),
-              "select mean_ratio > 0 from decipherRaw where id = '%s' and "
+              "select mean_ratio from decipherRaw where id = '%s' and "
               "chr = '%s' and start = %d and end = %d",
 	          decipherId, decipherChrom, bed->chromStart+1, bed->chromEnd);
 	sr = sqlGetResult(conn, query);
         if ((row = sqlNextRow(sr)) != NULL)
             {
-	    if (sameWord(row[0], "1"))
+            if (isEmpty(row[0]) || (atof(row[0]) == 0.0))
+                {
+                col = MG_GRAY;
+                }
+	    else if (atof(row[0]) > 0)
                 {
                 col = MG_BLUE;
                 }
 	    else
 		{
                 col = MG_RED;
 		}
 	    }
 	sqlFreeResult(&sr);
-        /* add more logic here to check for mean_ratio = 0
-           (which is a problem to be fixed by DECIPHER */
+	}
+    }
+hFreeConn(&conn);
+return(col);
+}
 
+static char *decipherSnvsPhenotypeList(char *name)
+/* Return list of diseases associated with a DECIPHER SNVs entry */
+{
+char query[256];
+static char list[4096];
+struct sqlConnection *conn = hAllocConn(database);
+if (sqlFieldIndex(conn, "decipherSnvsRaw", "phenotypes") >= 0)
+    {
+    list[0] = '\0';
     sqlSafef(query, sizeof(query),
-	       "select mean_ratio = 0 from decipherRaw where id = '%s' and "
-           "chr = '%s' and start = %d and end = %d",
+        "select phenotypes from decipherSnvsRaw where id='%s'", name);
+    struct sqlResult *sr = sqlMustGetResult(conn, query);
+    char **row = sqlNextRow(sr);
+    if ((row != NULL) && strlen(row[0]) >= 1)
+        {
+        char *prettyResult = replaceChars(row[0], "|", "; ");
+        safecpy(list, sizeof(list), prettyResult);
+        // freeMem(prettyResult);
+        }
+    sqlFreeResult(&sr);
+    }
+else
+    {
+    sqlSafef(query, sizeof(query),
+        "select distinct phenotype from decipherSnvsRaw where id='%s' order by phenotype", name);
+    hFreeConn(&conn);
+    return collapseRowsFromQuery(query, "; ", 20);
+    }
+hFreeConn(&conn);
+return list;
+}
+
+void decipherSnvsLoad(struct track *tg)
+/* Load DECIPHER SNVs items with extra labels from decipherSnvsPhenotypeList. */
+{
+bedPlusLabelLoad(tg, decipherSnvsPhenotypeList);
+}
+
+Color decipherSnvsColor(struct track *tg, void *item, struct hvGfx *hvg)
+/* Return color to draw DECIPHER SNV entry */
+{
+struct bed *bed = item;
+int col = tg->ixColor;
+struct sqlConnection *conn = hAllocConn(database);
+struct sqlResult *sr;
+char **row;
+char query[256];
+char cond_str[256];
+char *decipherId = NULL;
+
+/* So far, we can just remove "chr" from UCSC chrom names to get DECIPHER names */
+char *decipherChrom = bed->chrom;
+if (startsWithNoCase("chr", bed->chrom))
+    decipherChrom += 3;
+
+/* color scheme:
+    BLACK:      If the entry is likely or definitely pathogenic
+    DARK GRAY:  If the entry is uncertain or unknown
+    LIGHT GRAY: If the entry is likely or definitely benign
+*/
+
+sqlSafefFrag(cond_str, sizeof(cond_str),"name='%s' ", bed->name);
+decipherId = sqlGetField(database, "decipherSnvs", "name", cond_str);
+
+if (decipherId != NULL)
+    {
+    if (hTableExists(database, "decipherSnvsRaw"))
+        {
+        sqlSafef(query, sizeof(query), "select pathogenicity from decipherSnvsRaw where "
+            "id = '%s' and chr = '%s' and start = '%d' and end = '%d'",
             decipherId, decipherChrom, bed->chromStart+1, bed->chromEnd);
 	sr = sqlGetResult(conn, query);
+        col = MG_GRAY;
         if ((row = sqlNextRow(sr)) != NULL)
             {
-	    if (sameWord(row[0], "1"))
+            char *ucPathogenicity = cloneString(row[0]);
+            strUpper(ucPathogenicity);
+	    if (endsWith(ucPathogenicity, "PATHOGENIC"))
                 {
-                col = MG_GRAY;
+                col = MG_BLACK;
+                }
+	    else if (endsWith(ucPathogenicity, "BENIGN"))
+		{
+                col = MAKECOLOR_32(200,200,200);
 		}
+            // freeMem(ucPathogenicity);
 	    }
 	sqlFreeResult(&sr);
 	}
     }
 hFreeConn(&conn);
 return(col);
 }
 
-void decipherMethods(struct track *tg)
-/* Methods for DECIPHER track. */
+void decipherCnvsMethods(struct track *tg)
+/* Methods for DECIPHER CNVs track. */
+{
+tg->loadItems   = decipherCnvsLoad;
+tg->itemColor   = decipherCnvsColor;
+tg->itemNameColor = decipherCnvsColor;
+tg->drawItemAt  = bedPlusLabelDrawAt;
+tg->mapItem     = bedPlusLabelMapItem;
+tg->nextPrevExon = simpleBedNextPrevEdge;
+}
+
+void decipherSnvsMethods(struct track *tg)
+/* Methods for DECIPHER SNVs track. */
 {
-tg->loadItems   = decipherLoad;
-tg->itemColor   = decipherColor;
-tg->itemNameColor = decipherColor;
+tg->loadItems   = decipherSnvsLoad;
+tg->itemColor   = decipherSnvsColor;
+tg->itemNameColor = decipherSnvsColor;
 tg->drawItemAt  = bedPlusLabelDrawAt;
 tg->mapItem     = bedPlusLabelMapItem;
 tg->nextPrevExon = simpleBedNextPrevEdge;
 }
 
 char *emptyName(struct track *tg, void *item)
 /* Return name of item. */
 {
 return("");
 }
 
 void rdmrMethods(struct track *tg)
 /* Methods for R-DMR track. */
 {
 tg->itemName = emptyName;
@@ -14612,31 +14706,32 @@
 registerTrackHandler("ctgPos", contigMethods);
 registerTrackHandler("ctgPos2", contigMethods);
 registerTrackHandler("bactigPos", bactigMethods);
 registerTrackHandler("gold", goldMethods);
 registerTrackHandler("gap", gapMethods);
 registerTrackHandler("genomicDups", genomicDupsMethods);
 registerTrackHandler("clonePos", coverageMethods);
 registerTrackHandler("genieKnown", genieKnownMethods);
 registerTrackHandler("knownGene", knownGeneMethods);
 registerTrackHandler("h1n1_0602Seq", h1n1SeqMethods);
 registerTrackHandler("h1n1b_0514Seq", h1n1SeqMethods);
 registerTrackHandler("hg17Kg", hg17KgMethods);
 registerTrackHandler("superfamily", superfamilyMethods);
 registerTrackHandler("gad", gadMethods);
 registerTrackHandler("rdmr", rdmrMethods);
-registerTrackHandler("decipher", decipherMethods);
+registerTrackHandler("decipher", decipherCnvsMethods);
+registerTrackHandler("decipherSnvs", decipherSnvsMethods);
 registerTrackHandler("rgdQtl", rgdQtlMethods);
 registerTrackHandler("rgdRatQtl", rgdQtlMethods);
 registerTrackHandler("refGene", refGeneMethods);
 registerTrackHandler("ncbiRefSeq", ncbiRefSeqMethods);
 registerTrackHandler("ncbiRefSeqCurated", ncbiRefSeqMethods);
 registerTrackHandler("ncbiRefSeqPredicted", ncbiRefSeqMethods);
 // registerTrackHandler("ncbiRefSeqOther", ncbiRefSeqMethods); has become bed12
 registerTrackHandler("rgdGene2", rgdGene2Methods);
 registerTrackHandler("blastMm6", blastMethods);
 registerTrackHandler("blastDm1FB", blastMethods);
 registerTrackHandler("blastDm2FB", blastMethods);
 registerTrackHandler("blastCe3WB", blastMethods);
 registerTrackHandler("blastHg16KG", blastMethods);
 registerTrackHandler("blastHg17KG", blastMethods);
 registerTrackHandler("blastHg18KG", blastMethods);