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)"); }