e9ce012a18f0dd54154f2771fcc380b8626e821e
markd
  Sun Mar 3 00:10:02 2013 -0800
Added highlighting of GENCODE transcripts based on annotation method.Also fixed bug with annotation method filtering for `automatic'.  Added
support for filtering by `manual and automatic' method.

diff --git src/hg/hgTracks/gencodeTracks.c src/hg/hgTracks/gencodeTracks.c
index 3f505ed..747925e 100644
--- src/hg/hgTracks/gencodeTracks.c
+++ src/hg/hgTracks/gencodeTracks.c
@@ -7,35 +7,38 @@
 #include "genePredReader.h"
 #include "genePred.h"
 
 struct gencodeQuery
 /* structure used to store information about the query being assembled.
  * this allows a join to bring in additional data without having to
  * do repeated queries. */
 {
     struct dyString *fields;                // select fields
     struct dyString *from;                  // from clause
     struct dyString *where;                 // where clause
     boolean isGenePredX;                    // does this have the extended fields?
     int nextFieldCol;                       // next available column in result row
     int supportLevelCol;                    // support level column if joined for highlighting, or -1 
     int transcriptTypeCol;                  // transcript type column if joined for highlighting, or -1 
+    int transcriptSourceCol;                // transcript source column if joined for method highlighting, or -1 
     filterBy_t *supportLevelHighlight;      // choices for support level highlighting if not NULL
     filterBy_t *transcriptTypeHighlight;    // choices for transcript type highlighting if not NULL
+    filterBy_t *transcriptMethodHighlight;  // choices for transcript method highlighting if not NULL
     boolean joinAttrs;                      // join the wgEncodeGencodeAttrs table
     boolean joinTransSrc;                   // join the wgEncodeGencodeTranscriptSource table
     boolean joinSupportLevel;               // join the wgEncodeGencodeTranscriptionSupportLevel table
+    boolean joinTranscriptSource;            // join the wgEncodeGencodeTranscriptSource table
 };
 
 static struct gencodeQuery *gencodeQueryNew(void)
 /* construct a new gencodeQuery object */
 {
 struct gencodeQuery *gencodeQuery;
 AllocVar(gencodeQuery);
 gencodeQuery->fields = dyStringNew(0);
 gencodeQuery->from = dyStringNew(0);
 gencodeQuery->where = dyStringNew(0);
 gencodeQuery->supportLevelCol = -1;
 gencodeQuery->transcriptTypeCol = -1;
 return gencodeQuery;
 }
 
@@ -86,44 +89,46 @@
 static char buf[8];
 if (sameString(tslNum, "-1"))
     return "tslNA";
 else
     {
     safef(buf, sizeof(buf), "tsl%s", tslNum);
     return buf;
     }
 }
 
 static void filterByMethodChoiceQuery(char *choice, struct gencodeQuery *gencodeQuery)
 /* add SQL expression GENCODE transcript method choice. */
 {
 /*
  * example sources and categories:
- *    havana_ig_gene                manual & manual only
- *    ensembl_havana_transcript     manual & automatic
- *    havana                        manual & manual only
- *    ensembl                       automatic & automatic only
- *    mt_genbank_import             automatic & automatic only
+ *    havana_ig_gene                manual, manual only
+ *    ensembl_havana_transcript     manual, automatic & manual and automatic
+ *    havana                        manual, manual only
+ *    ensembl                       automatic, automatic only
+ *    mt_genbank_import             automatic, automatic only
  */
 if (sameString(choice, "manual"))
     dyStringAppend(gencodeQuery->where, "(transSrc.source like \"%havana%\")");
 else if (sameString(choice, "automatic"))
-    dyStringAppend(gencodeQuery->where, "((transSrc.source like \"%ensembl%\") or (transSrc.source not like \"%ensembl%\"))");
+    dyStringAppend(gencodeQuery->where, "((transSrc.source like \"%ensembl%\") or (transSrc.source not like \"%havana%\"))");
 else if (sameString(choice, "manual_only"))
     dyStringAppend(gencodeQuery->where, "((transSrc.source like \"%havana%\") and (transSrc.source not like \"%ensembl%\"))");
 else if (sameString(choice, "automatic_only"))
     dyStringAppend(gencodeQuery->where, "(transSrc.source not like \"%havana%\")");
+else if (sameString(choice, "manual_and_automatic"))
+    dyStringAppend(gencodeQuery->where, "((transSrc.source like \"%havana%\") and (transSrc.source like \"%ensembl%\"))");
 else
     errAbort("BUG: filterByMethodChoiceQuery missing choice: \"%s\"", choice);
 }
 
 static void filterByMethodChoicesQuery(filterBy_t *filterBy, struct gencodeQuery *gencodeQuery)
 /* add transcript source compare clauses */
 {
 struct slName *choice = NULL;
 for (choice = filterBy->slChoices; choice != NULL; choice = choice->next)
     {
     if (choice != filterBy->slChoices)
         dyStringAppend(gencodeQuery->where, " or ");
     filterByMethodChoiceQuery(choice->name, gencodeQuery);
     }
 }
@@ -209,37 +214,50 @@
 dyStringAppend(gencodeQuery->fields, ", supLevel.level");
 gencodeQuery->supportLevelCol = gencodeQuery->nextFieldCol++;
 gencodeQuery->supportLevelHighlight = highlightBy;
 gencodeQuery->joinSupportLevel = TRUE;
 }
 
 static void highlightByTranscriptTypeQuery(struct track *tg, filterBy_t *highlightBy, struct gencodeQuery *gencodeQuery)
 /* generate SQL where clause for obtaining transcript type for highlighting */
 {
 dyStringAppend(gencodeQuery->fields, ", attrs.transcriptType");
 gencodeQuery->transcriptTypeCol = gencodeQuery->nextFieldCol++;
 gencodeQuery->transcriptTypeHighlight = highlightBy;
 gencodeQuery->joinAttrs = TRUE;
 }
 
+
+static void highlightByTranscriptMethodQuery(struct track *tg, filterBy_t *highlightBy, struct gencodeQuery *gencodeQuery)
+/* generate SQL where clause for obtaining transcript type for highlighting */
+{
+gencodeQuery->joinTransSrc = TRUE;
+dyStringAppend(gencodeQuery->fields, ", transSrc.source");
+gencodeQuery->transcriptSourceCol = gencodeQuery->nextFieldCol++;
+gencodeQuery->transcriptMethodHighlight = highlightBy;
+gencodeQuery->joinAttrs = TRUE;
+}
+
 static void gencodeHighlightByQuery(struct track *tg, filterBy_t *highlightBy, struct gencodeQuery *gencodeQuery)
 /* Handle a highlight by category.  highlightBy object will be saved in gencodeQuery */
 {
 if (sameString(highlightBy->column, "supportLevel"))
     highlightBySupportLevelQuery(tg, highlightBy, gencodeQuery);
 else if (sameString(highlightBy->column, "attrs.transcriptType"))
     highlightByTranscriptTypeQuery(tg, highlightBy, gencodeQuery);
+else if (sameString(highlightBy->column, "transcriptMethod"))
+    highlightByTranscriptMethodQuery(tg, highlightBy, gencodeQuery);
 else
     errAbort("BUG: gencodeHighlightByQuery unknown highlight column: \"%s\"", highlightBy->column);
 }
 
 static void gencodeHighlightBySetQuery(struct track *tg, struct gencodeQuery *gencodeQuery)
 /* build add join and fields to include to provide data for highlighting.  This results
  * in extra columns being returned. */
 {
 filterBy_t *highlightBySet = highlightBySetGet(tg->tdb, cart, NULL);
 filterBy_t *highlightBy;
 while ((highlightBy = slPopHead(&highlightBySet)) != NULL)
     {
     if (!filterByAllChosen(highlightBy))
         gencodeHighlightByQuery(tg, highlightBy, gencodeQuery);
     else
@@ -253,46 +271,95 @@
 if (gencodeQuery->supportLevelHighlight == NULL)
     return FALSE;  // no highlighting by support level
 else
     return slNameInList(gencodeQuery->supportLevelHighlight->slChoices, tslNumStrToSym(row[gencodeQuery->supportLevelCol]));
 }
 
 static bool highlightByTranscriptTypeSelected(char **row, struct gencodeQuery *gencodeQuery)
 /* is the transcript type associated with this transcript selected? */
 {
 if (gencodeQuery->transcriptTypeHighlight == NULL)
     return FALSE;  // no highlighting by transcript type
 else
     return slNameInList(gencodeQuery->transcriptTypeHighlight->slChoices, row[gencodeQuery->transcriptTypeCol]);
 }
 
+static bool highlightByTranscriptMethodMatch(char *choice, char *transSource)
+/* check if the transcript source matches the specified choice */
+{
+if (sameString(choice, "manual"))
+    {
+    if (containsStringNoCase(transSource, "havana"))
+        return TRUE;
+    }
+else if (sameString(choice, "automatic"))
+    {
+    if (containsStringNoCase(transSource, "ensembl") || !containsStringNoCase(transSource, "havana"))
+        return TRUE;
+    }
+else if (sameString(choice, "manual_only"))
+    {
+    if (containsStringNoCase(transSource, "havana") && !containsStringNoCase(transSource, "ensembl"))
+        return TRUE;
+    }
+else if (sameString(choice, "automatic_only"))
+    {
+    if (!containsStringNoCase(transSource, "havana"))
+        return TRUE;
+    }
+else if (sameString(choice, "manual_and_automatic"))
+    {
+    if (containsStringNoCase(transSource, "havana") && containsStringNoCase(transSource, "ensembl"))
+        return TRUE;
+    }
+else
+    errAbort("BUG: highlightByTranscriptMethodMatch missing choice: \"%s\"", choice);
+return FALSE;
+}
+
+static bool highlightByTranscriptMethodSelected(char **row, struct gencodeQuery *gencodeQuery)
+/* is the transcript type associated with this transcript selected? */
+{
+if (gencodeQuery->transcriptMethodHighlight != NULL)
+    {
+    struct slName *choice;
+    for (choice = gencodeQuery->transcriptMethodHighlight->slChoices; choice != NULL; choice = choice->next)
+        {
+        if (highlightByTranscriptMethodMatch(choice->name, row[gencodeQuery->transcriptSourceCol]))
+            return TRUE;
+        }
+    }
+return FALSE;
+}
+
 static unsigned getHighlightColor(struct track *tg)
 /* get the highlightColor from trackDb, or a default if not found */
 {
 unsigned char red = 255, green = 165, blue = 0; // Orange default
 char *colorStr = trackDbSetting(tg->tdb, "highlightColor");
 if (colorStr != NULL)
     parseColor(colorStr, &red, &green, &blue);
 return MAKECOLOR_32(red, green, blue);
 }
 
 static void highlightByGetColor(char **row, struct gencodeQuery *gencodeQuery, unsigned highlightColor,
                                 struct linkedFeatures *lf)
 /* compute the highlight color based on a extra fields returned in a row, setting
  * the linkedFeatures field */
 {
-if (highlightBySupportLevelSelected(row, gencodeQuery) || highlightByTranscriptTypeSelected(row, gencodeQuery))
+if (highlightBySupportLevelSelected(row, gencodeQuery) || highlightByTranscriptTypeSelected(row, gencodeQuery)
+    || highlightByTranscriptMethodSelected(row, gencodeQuery))
     {
     lf->highlightColor = highlightColor;
     lf->highlightMode = highlightBackground;
     }
 }
 
 static void addQueryTables(struct track *tg, struct gencodeQuery *gencodeQuery)
 /* add required from tables and joins */
 {
 dyStringPrintf(gencodeQuery->from, "%s g", tg->table);
 if (gencodeQuery->joinAttrs)
     {
     dyStringPrintf(gencodeQuery->from, ", %s attrs", trackDbRequiredSetting(tg->tdb, "wgEncodeGencodeAttrs"));
     dyStringAppend(gencodeQuery->where, " and (attrs.transcriptId = g.name)");
     }