6175649026c35358cc0871c3f2cdf39328736885
markd
  Sun Oct 30 20:44:31 2022 -0700
initial implementation of all gencode transcript rank filters, not GUI yet

diff --git src/hg/hgTracks/gencodeTracks.c src/hg/hgTracks/gencodeTracks.c
index 6fd9684..f3d71db 100644
--- src/hg/hgTracks/gencodeTracks.c
+++ src/hg/hgTracks/gencodeTracks.c
@@ -1,680 +1,702 @@
 /* gencodeTracks - ENCODE GENCODE Genes tracks for both pilot and production ENCODE.
  * although these are used fundamentally different approaches to display */
 
 /* Copyright (C) 2014 The Regents of the University of California 
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 #include "common.h"
+#include "gencodeTracksCommon.h"
 #include "hgTracks.h"
 #include "hdb.h"
 #include "gencodeIntron.h"
 #include "genePredReader.h"
 #include "genePred.h"
 #include "encode/wgEncodeGencodeAttrs.h"
 
 /* item label symbolic names and constants.  This must be
  * in sync with lib/hui.c:gencodeLabelControls() */
 enum
 /* bit set of item labels */
 {
     ITEM_LABEL_GENE_NAME = 0x01,
     ITEM_LABEL_GENE_ID = 0x02,
     ITEM_LABEL_TRANSCRIPT_ID = 0x04
 };
 
 static struct
 /* label names to constant */
 {
     char *name;
     unsigned flag;
 } itemLabelCartVarNamesMap[] = {
     {"geneName", ITEM_LABEL_GENE_NAME},
     {"geneId", ITEM_LABEL_GENE_ID},
     {"transcriptId", ITEM_LABEL_TRANSCRIPT_ID},
     {NULL, 0}
 };
 
 
 /* function type that returns filter or highlight types */
 typedef filterBy_t* (*filterBySetGetFuncType)(struct trackDb *tdb, struct cart *cart, char *name);
 
 struct gencodeQuery
 /* Structure used to store information about the query being assembled.
  * Joins are for the purpose of filtering results, and in some cases, returning
  * additional information. */
 {
     struct dyString *fields;                // select fields
     struct dyString *from;                  // from clause
     struct dyString *where;                 // where clause
     int genePredNumColumns;                 // number of genePred columns returned
     int attrsNumColumns;                    // number of attr columns returned
     boolean isGenePredX;                    // does this have the extended fields?
     boolean isFiltered;                     // are there filters on the query?
     boolean joinAttrs;                      // join the wgEncodeGencodeAttrs table
     boolean joinSupportLevel;               // join the wgEncodeGencodeTranscriptionSupportLevel table
     boolean joinTranscriptSource;           // join the wgEncodeGencodeTranscriptSource table
     boolean joinTag;                        // join the wgEncodeGencodeTag table (one to many, so filtering only)
 };
 
 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);
 return gencodeQuery;
 }
 
 static void gencodeQueryFree(struct gencodeQuery **gencodeQueryPtr)
 /* construct a new gencodeQuery object */
 {
 struct gencodeQuery *gencodeQuery = *gencodeQueryPtr;
 if (gencodeQuery != NULL)
     {
     dyStringFree(&gencodeQuery->fields);
     dyStringFree(&gencodeQuery->from);
     dyStringFree(&gencodeQuery->where);
     freeMem(gencodeQuery);
     *gencodeQueryPtr = NULL;
     }
 }
 
 static void gencodeQueryBeginSubWhere(struct gencodeQuery *gencodeQuery)
 /* begin adding new where sub-clause */
 {
 if (dyStringLen(gencodeQuery->where) > 0)
     sqlDyStringPrintf(gencodeQuery->where, " and ");
 sqlDyStringPrintf(gencodeQuery->where, "(");
 }
 
 static void gencodeQueryEndSubWhere(struct gencodeQuery *gencodeQuery)
 /* finish adding new where sub-clause */
 {
 sqlDyStringPrintf(gencodeQuery->where, ")");
 }
 
 static struct genePred *gencodeQueryGenePred(struct gencodeQuery *gencodeQuery,
                                              char **row)
 /* get genePred from a query results */
 {
 return genePredExtLoad(row, gencodeQuery->genePredNumColumns);
 }
 
 static struct wgEncodeGencodeAttrs *gencodeQueryAttrs(struct gencodeQuery *gencodeQuery,
                                                       char **row)
 /* get attributes from a query results, or NULL if not requested */
 {
 if (gencodeQuery->attrsNumColumns > 0)
     return wgEncodeGencodeAttrsLoad(row + gencodeQuery->genePredNumColumns, gencodeQuery->attrsNumColumns);
 else
     return NULL;
 }
 
 static boolean anyFilterBy(struct track *tg, filterBySetGetFuncType filterBySetGetFunc)
 /* check if any filters were specified of the particular type */
 {
 filterBy_t *filterBySet = filterBySetGetFunc(tg->tdb, cart, NULL);
 filterBy_t *filterBy;
 boolean someFilters = FALSE;
 for (filterBy = filterBySet; (filterBy != NULL) && !someFilters; filterBy = filterBy->next)
     {
     if (!filterByAllChosen(filterBy))
         someFilters = TRUE;
     }   
 filterBySetFree(&filterBySet);
 return someFilters;
 }
 
 static char *tslSymToNumStr(char *tslSym)
 /* convert a transcription support level string (tsl1..tsl5, tslN), to 
  * a numeric string ("1".."5", "-1") */
 {
 if (sameString(tslSym, "tslNA"))
     return "-1";
 else
     return tslSym+3;
 }
 
 static void filterByMethodChoiceQuery(char *choice, struct gencodeQuery *gencodeQuery)
 /* add SQL expression for GENCODE transcript method choice. */
 {
 /*
  * example sources and categories:
  *    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"))
     sqlDyStringPrintf(gencodeQuery->where, "(transSrc.source like \"%%havana%%\")");
 else if (sameString(choice, "automatic"))
     sqlDyStringPrintf(gencodeQuery->where, "((transSrc.source like \"%%ensembl%%\") or (transSrc.source not like \"%%havana%%\"))");
 else if (sameString(choice, "manual_only"))
     sqlDyStringPrintf(gencodeQuery->where, "((transSrc.source like \"%%havana%%\") and (transSrc.source not like \"%%ensembl%%\"))");
 else if (sameString(choice, "automatic_only"))
     sqlDyStringPrintf(gencodeQuery->where, "(transSrc.source not like \"%%havana%%\")");
 else if (sameString(choice, "manual_and_automatic"))
     sqlDyStringPrintf(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)
         sqlDyStringPrintf(gencodeQuery->where, " or ");
     filterByMethodChoiceQuery(choice->name, gencodeQuery);
     }
 }
 
 static void filterByMethodQuery(struct track *tg, filterBy_t *filterBy, struct gencodeQuery *gencodeQuery)
 /* generate SQL where clause for annotation method filtering */
 {
 gencodeQueryBeginSubWhere(gencodeQuery);
 filterByMethodChoicesQuery(filterBy, gencodeQuery);
 gencodeQuery->joinTranscriptSource = TRUE;
 gencodeQueryEndSubWhere(gencodeQuery);
 }
 
 static void filterBySupportLevelChoiceQuery(char *choice, struct gencodeQuery *gencodeQuery)
 /* add SQL expression GENCODE support choice. */
 {
 /* table is numeric (silly me), and string is tsl1..tsl5 or tslNA */
 sqlDyStringPrintf(gencodeQuery->where, "(supLevel.level = %d)", atoi(tslSymToNumStr(choice)));
 }
 
 static void filterBySupportLevelChoicesQuery(filterBy_t *filterBy, struct gencodeQuery *gencodeQuery)
 /* add support level compare clauses */
 {
 struct slName *choice = NULL;
 for (choice = filterBy->slChoices; choice != NULL; choice = choice->next)
     {
     if (choice != filterBy->slChoices)
         sqlDyStringPrintf(gencodeQuery->where, " or ");
     filterBySupportLevelChoiceQuery(choice->name, gencodeQuery);
     }
 }
 
 static void filterBySupportLevelQuery(struct track *tg, filterBy_t *filterBy, struct gencodeQuery *gencodeQuery)
 /* generate SQL where clause for annotation support level filtering */
 {
 gencodeQueryBeginSubWhere(gencodeQuery);
 filterBySupportLevelChoicesQuery(filterBy, gencodeQuery);
 gencodeQuery->joinSupportLevel = TRUE;
 gencodeQueryEndSubWhere(gencodeQuery);
 }
 
 static void filterByTagChoiceQuery(char *choice, struct gencodeQuery *gencodeQuery)
 /* add SQL expression GENCODE tag choice. */
 {
 sqlDyStringPrintf(gencodeQuery->where, "(tag.tag = \"%s\")", choice);
 }
 
 static void filterByTagChoicesQuery(filterBy_t *filterBy, struct gencodeQuery *gencodeQuery)
 /* add tag compare clauses */
 {
 struct slName *choice = NULL;
 for (choice = filterBy->slChoices; choice != NULL; choice = choice->next)
     {
     if (choice != filterBy->slChoices)
         sqlDyStringPrintf(gencodeQuery->where, " or ");
     filterByTagChoiceQuery(choice->name, gencodeQuery);
     }
 }
 
 static void filterByTagQuery(struct track *tg, filterBy_t *filterBy, struct gencodeQuery *gencodeQuery)
 /* generate SQL where clause for annotation tag filtering */
 {
 gencodeQueryBeginSubWhere(gencodeQuery);
 filterByTagChoicesQuery(filterBy, gencodeQuery);
 gencodeQuery->joinTag = TRUE;
 gencodeQueryEndSubWhere(gencodeQuery);
 }
 
 static void filterByAttrsQuery(struct track *tg, filterBy_t *filterBy, struct gencodeQuery *gencodeQuery)
 /* handle adding on filterBy clause for attributes table */
 {
 char *clause = filterByClause(filterBy);
 if (clause != NULL)
     {
     gencodeQueryBeginSubWhere(gencodeQuery);
     sqlDyStringPrintf(gencodeQuery->where, "%-s", clause);
     gencodeQuery->joinAttrs = TRUE;
     gencodeQueryEndSubWhere(gencodeQuery);
     freeMem(clause);
     }
 }
 
 static void gencodeFilterByQuery(struct track *tg, filterBy_t *filterBy, struct gencodeQuery *gencodeQuery)
 /* handle adding on filterBy clause for gencode */
 {
 if (sameString(filterBy->column, "transcriptMethod"))
     filterByMethodQuery(tg, filterBy, gencodeQuery);
 else if (sameString(filterBy->column, "supportLevel"))
     filterBySupportLevelQuery(tg, filterBy, gencodeQuery);
 else if (sameString(filterBy->column, "tag"))
     filterByTagQuery(tg, filterBy, gencodeQuery);
 else if (startsWith("attrs.", filterBy->column))
     filterByAttrsQuery(tg, filterBy, gencodeQuery);
 else
     errAbort("gencodeFilterByQuery: don't know how to filter on column \"%s\"", filterBy->column);
 gencodeQuery->isFiltered = TRUE;
 }
 
 static void gencodeFilterBySetQuery(struct track *tg, filterBySetGetFuncType filterBySetGetFunc, struct gencodeQuery *gencodeQuery)
 /* build where sql clauses for filters or highlights. */
 {
 filterBy_t *filterBySet = filterBySetGetFunc(tg->tdb, cart, NULL);
 filterBy_t *filterBy;
 for (filterBy = filterBySet; filterBy != NULL; filterBy = filterBy->next)
     {
     if (!filterByAllChosen(filterBy))
         gencodeFilterByQuery(tg, filterBy, gencodeQuery);
     }
 filterBySetFree(&filterBySet);
 }
 
+static void addFilterMaxTranscripsByRange(struct sqlConnection *conn, struct track *tg, struct gencodeQuery *gencodeQuery)
+/* Add query for the maximum number of transcripts to display if requested and
+ * if transcriptRank is available in attrs */
+{
+// FIXME: tmp until we can get it in the UI
+int maxTrans = cartCgiUsualInt(cart, "maxTrans", 0);
+if (maxTrans == 0)
+    return;  // zero disables
+// do we have transcriptRank column?
+if (!sqlColumnExists(conn, gencodeGetTableName(tg->tdb, "wgEncodeGencodeAttrs"), "transcriptRank"))
+    return ;
+
+// rank starts at 1, so anything less than or equal to max will be included
+gencodeQueryBeginSubWhere(gencodeQuery);
+sqlDyStringPrintf(gencodeQuery->where, "attrs.transcriptRank <= %d", maxTrans);
+gencodeQuery->joinAttrs = TRUE;
+gencodeQueryEndSubWhere(gencodeQuery);
+gencodeQuery->isFiltered = TRUE;
+}
+
 static void addQueryTables(struct track *tg, struct gencodeQuery *gencodeQuery)
 /* add required from tables and joins */
 {
 sqlDyStringPrintf(gencodeQuery->from, "%s g", tg->table);
 if (gencodeQuery->joinAttrs)
     {
-    sqlDyStringPrintf(gencodeQuery->from, ", %s attrs", trackDbRequiredSetting(tg->tdb, "wgEncodeGencodeAttrs"));
+    sqlDyStringPrintf(gencodeQuery->from, ", %s attrs", gencodeGetTableName(tg->tdb, "wgEncodeGencodeAttrs"));
     sqlDyStringPrintf(gencodeQuery->where, " and (attrs.transcriptId = g.name)");
     }
 if (gencodeQuery->joinTranscriptSource)
     {
-    sqlDyStringPrintf(gencodeQuery->from, ", %s transSrc", trackDbRequiredSetting(tg->tdb, "wgEncodeGencodeTranscriptSource"));
+    sqlDyStringPrintf(gencodeQuery->from, ", %s transSrc", gencodeGetTableName(tg->tdb, "wgEncodeGencodeTranscriptSource"));
     sqlDyStringPrintf(gencodeQuery->where, " and (transSrc.transcriptId = g.name)");
     }
 if (gencodeQuery->joinSupportLevel)
     {
-    sqlDyStringPrintf(gencodeQuery->from, ", %s supLevel", trackDbRequiredSetting(tg->tdb, "wgEncodeGencodeTranscriptionSupportLevel"));
+    sqlDyStringPrintf(gencodeQuery->from, ", %s supLevel", gencodeGetTableName(tg->tdb, "wgEncodeGencodeTranscriptionSupportLevel"));
     sqlDyStringPrintf(gencodeQuery->where, " and (supLevel.transcriptId = g.name)");
     }
 if (gencodeQuery->joinTag)
     {
-    sqlDyStringPrintf(gencodeQuery->from, ", %s tag", trackDbRequiredSetting(tg->tdb, "wgEncodeGencodeTag"));
+    sqlDyStringPrintf(gencodeQuery->from, ", %s tag", gencodeGetTableName(tg->tdb, "wgEncodeGencodeTag"));
     sqlDyStringPrintf(gencodeQuery->where, " and (tag.transcriptId = g.name)");
     }
 }
 
-static void addQueryCommon(struct track *tg, filterBySetGetFuncType filterBySetGetFunc, struct gencodeQuery *gencodeQuery)
+static void addQueryCommon(struct sqlConnection *conn, struct track *tg, filterBySetGetFuncType filterBySetGetFunc, struct gencodeQuery *gencodeQuery)
 /* Add tables and joins for both gene and highlight queries */
 {
 // bin range overlap part
 hAddBinToQuery(winStart, winEnd, gencodeQuery->where);
 sqlDyStringPrintf(gencodeQuery->where, "(g.chrom = \"%s\") and (g.txStart < %u) and (g.txEnd > %u)", chromName, winEnd, winStart);
 
 gencodeFilterBySetQuery(tg, filterBySetGetFunc, gencodeQuery);
+addFilterMaxTranscripsByRange(conn, tg, gencodeQuery);
 addQueryTables(tg, gencodeQuery);
 }
 
 static struct sqlResult *executeQuery(struct sqlConnection *conn, struct gencodeQuery *gencodeQuery)
 /* execute the actual SQL query */
 {
 struct dyString *query = dyStringNew(0);
 sqlDyStringPrintf(query, "select %-s from %-s where %-s", 
     dyStringContents(gencodeQuery->fields), dyStringContents(gencodeQuery->from), dyStringContents(gencodeQuery->where));
 struct sqlResult *sr = sqlGetResult(conn, dyStringContents(query));
 dyStringFree(&query);
 return sr;
 }
 
 static boolean annotIsGenePredExt(struct track *tg)
 /* determine if a table has genePred extended fields.  two-way consensus
  * pseudo doesn't have them. */
 {
 struct sqlConnection *conn = hAllocConn(database);
 struct slName *fields = sqlFieldNames(conn, tg->table);
 hFreeConn(&conn);
 boolean isGenePredX = slNameInList(fields, "score");
 slFreeList(&fields);
 return isGenePredX;
 }
 
 static void geneQueryAddGenePredCols(struct track *tg,
                                      struct gencodeQuery *gencodeQuery)
 /* add genePred columns to query */
 {
 gencodeQuery->isGenePredX = annotIsGenePredExt(tg);
 sqlDyStringPrintf(gencodeQuery->fields, "g.name, g.chrom, g.strand, g.txStart, g.txEnd, g.cdsStart, g.cdsEnd, g.exonCount, g.exonStarts, g.exonEnds");
 gencodeQuery->genePredNumColumns = GENEPRED_NUM_COLS;
 
 if (gencodeQuery->isGenePredX)
     {
     sqlDyStringPrintf(gencodeQuery->fields, ", g.score, g.name2, g.cdsStartStat, g.cdsEndStat, g.exonFrames");
     gencodeQuery->genePredNumColumns = GENEPREDX_NUM_COLS;
     }
 }
 
 static void geneQueryAddAttrsCols(struct track *tg, struct sqlConnection *conn,
                                   struct gencodeQuery *gencodeQuery)
 /* add attributes columns to query */
 {
-struct slName *fields = sqlFieldNames(conn, trackDbRequiredSetting(tg->tdb, "wgEncodeGencodeAttrs"));
+struct slName *fields = sqlFieldNames(conn, gencodeGetTableName(tg->tdb, "wgEncodeGencodeAttrs"));
 
 sqlDyStringPrintf(gencodeQuery->fields, ", ");
 sqlDyStringPrintf(gencodeQuery->fields, "attrs.geneId, attrs.geneName, attrs.geneType, attrs.geneStatus, attrs.transcriptId, attrs.transcriptName, attrs.transcriptType, attrs.transcriptStatus, attrs.havanaGeneId, attrs.havanaTranscriptId, attrs.ccdsId, attrs.level, attrs.transcriptClass");
 gencodeQuery->attrsNumColumns = WGENCODEGENCODEATTRS_MIM_NUM_COLS;
 if (slNameInList(fields, "proteinId"))
     {
     sqlDyStringPrintf(gencodeQuery->fields, ", attrs.proteinId");
     gencodeQuery->attrsNumColumns++;
     }
 if (slNameInList(fields, "transcriptRank"))
     {
     sqlDyStringPrintf(gencodeQuery->fields, ", attrs.transcriptRank");
     gencodeQuery->attrsNumColumns = WGENCODEGENCODEATTRS_NUM_COLS;
     }
 gencodeQuery->joinAttrs = TRUE;
 }
 
-static struct gencodeQuery *geneQueryConstruct(struct track *tg,
-                                               struct sqlConnection *conn,
+static struct gencodeQuery *geneQueryConstruct(struct sqlConnection *conn,
+                                               struct track *tg,
                                                boolean includeAttrs)
 /* construct the query for a GENCODE records, which includes filters. */
 {
 struct gencodeQuery *gencodeQuery = gencodeQueryNew();
 geneQueryAddGenePredCols(tg, gencodeQuery);
 if (includeAttrs)
     geneQueryAddAttrsCols(tg, conn, gencodeQuery);
-addQueryCommon(tg, filterBySetGet, gencodeQuery);
+addQueryCommon(conn, tg, filterBySetGet, gencodeQuery);
 return gencodeQuery;
 }
 
-static struct gencodeQuery *highlightQueryConstruct(struct track *tg)
+static struct gencodeQuery *highlightQueryConstruct(struct track *tg, struct sqlConnection *conn)
 /* construct the query for GENCODE ids which should be highlighted.
  * this essentially redoes the genePred query, only using the filter functions
  * and only getting ids */
 {
 struct gencodeQuery *gencodeQuery = gencodeQueryNew();
 sqlDyStringPrintf(gencodeQuery->fields, "g.name");
 
-addQueryCommon(tg, highlightBySetGet, gencodeQuery);
+addQueryCommon(conn, tg, highlightBySetGet, gencodeQuery);
 return gencodeQuery;
 }
 
 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(struct genePred *gp, struct hash *highlightIds, unsigned highlightColor,
                                 struct linkedFeatures *lf)
 /* compute the highlight color based on a extra fields returned in a row, setting
  * the linkedFeatures field */
 {
 if (hashLookup(highlightIds, gp->name) != NULL)
     {
     lf->highlightColor = highlightColor;
     lf->highlightMode = highlightBackground;
     }
 }
 
 static struct hash* loadHighlightIds(struct sqlConnection *conn, struct track *tg)
 /* Load ids (genePred names) in window for annotations to be highlighted. */
 {
 struct hash *highlightIds = hashNew(0);
-struct gencodeQuery *gencodeQuery = highlightQueryConstruct(tg);
+struct gencodeQuery *gencodeQuery = highlightQueryConstruct(tg, conn);
 struct sqlResult *sr = executeQuery(conn, gencodeQuery);
 char **row;
 while ((row = sqlNextRow(sr)) != NULL)
     hashAddInt(highlightIds, row[0], 1);
 sqlFreeResult(&sr);
 return highlightIds;
 }
 
 static boolean getLabelCartVar(struct track *tg, char *labelName, boolean *anyExistsP)
 /* get the cart label value for a label type. Sort TRUE in anyExistsP if the variable exists. */
 {
 char varSuffix[64];
 safef(varSuffix, sizeof(varSuffix), "label.%s", labelName);
 char *value = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, varSuffix, NULL);
 if (value != NULL)
     *anyExistsP = TRUE;
 return ((value != NULL) && !sameString(value, "0"));
 }
 
 static void setLabelCartVar(struct track *tg, char *labelName, boolean value)
 /* set one of the label type cart variables. */
 {
 char varName[256];
 safef(varName, sizeof(varName), "%s.label.%s", tg->track, labelName);
 cartSetBoolean(cart, varName, value);
 }
 
 static unsigned setFromOldLabelsVarsInCart(struct track *tg)
 /* If the old gencode label variable are set for this track, migrate to the new
  * variable.  This prevents labels from disappearing with the new old and an old cart.
  */
 {
 // logic from simpleTracks.c:genePredAssignConfiguredName()
 unsigned enabledLabels = 0;
 char *geneLabel = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, "label", "gene");
 if (sameString(geneLabel, "gene") || sameString(geneLabel, "name") || sameString(geneLabel, "both"))
     {
     setLabelCartVar(tg, "geneName", TRUE);
     enabledLabels |= ITEM_LABEL_GENE_NAME;
     }
 if (sameString(geneLabel, "accession") || sameString(geneLabel, "both"))
     {
     setLabelCartVar(tg, "transcriptId", TRUE);
     enabledLabels |= ITEM_LABEL_TRANSCRIPT_ID;
     }
 cartRemoveVariableClosestToHome(cart, tg->tdb, FALSE, "label");
 return enabledLabels;
 }
 
 static unsigned getEnabledLabels(struct track *tg)
 /* Look up each of the label type names in the cart to see if they are enabled,
  * Return bit set */
 {
 unsigned enabledLabels = 0;
 boolean anyExists = FALSE;
 int i;
 for (i = 0; itemLabelCartVarNamesMap[i].name != NULL; i++)
     {
     if (getLabelCartVar(tg, itemLabelCartVarNamesMap[i].name, &anyExists))
         enabledLabels |= itemLabelCartVarNamesMap[i].flag;
     }
 
 // if it looks like new track settings have never been configured, set from old.
 if ((enabledLabels == 0) && !anyExists)
     enabledLabels = setFromOldLabelsVarsInCart(tg);
 return enabledLabels;
 }
 
 static void concatItemName(char *name, int nameSize, char *value)
 /* add a name to the name buffer */
 {
 if (strlen(name) > 0)
     safecat(name, nameSize, "/");
 safecat(name, nameSize, value);
 }
 
 static char* getTranscriptLabel(unsigned enabledLabels, struct genePred *gp,
                                 struct wgEncodeGencodeAttrs *attrs)
 /* one type of label for a item in track */
 {
 char name[256];
 name[0] = '\0';
 if (enabledLabels & ITEM_LABEL_GENE_NAME)
     concatItemName(name, sizeof(name), gp->name2);
 if (enabledLabels & ITEM_LABEL_GENE_ID)
     concatItemName(name, sizeof(name), attrs->geneId);
 if (enabledLabels & ITEM_LABEL_TRANSCRIPT_ID)
     concatItemName(name, sizeof(name), gp->name);
 return cloneString(name);
 }
 
 static struct linkedFeatures *loadGencodeTranscript(struct track *tg, struct gencodeQuery *gencodeQuery, char **row,
                                                     unsigned enabledLabels, struct hash *highlightIds, unsigned highlightColor)
 /* load one genePred record into a linkedFeatures object */
 {
 struct genePred *gp = gencodeQueryGenePred(gencodeQuery, row);
 struct wgEncodeGencodeAttrs *attrs = gencodeQueryAttrs(gencodeQuery, row);  // maybe NULL
 struct linkedFeatures *lf = linkedFeaturesFromGenePred(tg, gp, TRUE);
 if (highlightIds != NULL)
     highlightByGetColor(gp, highlightIds, highlightColor, lf);
 if (gencodeQuery->isGenePredX)
     lf->extra = getTranscriptLabel(enabledLabels, gp, attrs);
 else
     lf->extra = cloneString(gp->name);
 wgEncodeGencodeAttrsFree(&attrs);
 return lf;
 }
 
 static void loadGencodeTrack(struct track *tg)
 /* Load genePreds in window info linked feature, with filtering, etc. */
 {
 struct sqlConnection *conn = hAllocConn(database);
 unsigned enabledLabels = getEnabledLabels(tg);
 boolean needAttrs = (enabledLabels & ITEM_LABEL_GENE_ID) != 0;  // only for certain labels
 struct hash *highlightIds = NULL;
 if (anyFilterBy(tg, highlightBySetGet))
     highlightIds = loadHighlightIds(conn, tg);
-struct gencodeQuery *gencodeQuery = geneQueryConstruct(tg, conn, needAttrs);
+struct gencodeQuery *gencodeQuery = geneQueryConstruct(conn, tg, needAttrs);
 struct sqlResult *sr = executeQuery(conn, gencodeQuery);
 struct linkedFeatures *lfList = NULL;
 unsigned highlightColor = getHighlightColor(tg);
 char **row;
 while ((row = sqlNextRow(sr)) != NULL)
     slAddHead(&lfList, loadGencodeTranscript(tg, gencodeQuery, row, enabledLabels, highlightIds, highlightColor));
 sqlFreeResult(&sr);
 hFreeConn(&conn);
 
 if (tg->visibility != tvDense)
     slSort(&lfList, linkedFeaturesCmpStart);
 else
     slReverse(&lfList);
 tg->items = lfList;
 if (gencodeQuery->isFiltered)
     labelTrackAsFiltered(tg);
 gencodeQueryFree(&gencodeQuery);
 hashFree(&highlightIds);
 }
 
 static char *gencodeGeneName(struct track *tg, void *item)
 /* Get name to use for Gencode gene item. */
 {
 struct linkedFeatures *lf = item;
 if (lf->extra != NULL)
     return lf->extra;
 else
     return lf->name;
 }
 
 static void gencodeGeneMethods(struct track *tg)
 /* Load up custom methods for ENCODE Gencode gene track */
 {
 tg->loadItems = loadGencodeTrack;
 tg->itemName = gencodeGeneName;
 }
 
 static void registerProductionTrackHandlers()
 /* register track handlers for production GENCODE tracks */
 {
 // ENCODE 1 legacy
 registerTrackHandler("wgEncodeSangerGencode", gencodeGeneMethods);
 
 // uses trackHandler attribute
 registerTrackHandler("wgEncodeGencode", gencodeGeneMethods);
 
 }
 
 static char *gencodePilotGeneName(struct track *tg, void *item)
 /* Get name to use for GENCODE pilot gene item. */
 {
 struct linkedFeatures *lf = item;
 if (lf->extra != NULL)
     return lf->extra;
 else
     return lf->name;
 }
 
 static void gencodePilotGeneMethods(struct track *tg)
 /* Load up custom methods for ENCODE Gencode gene track */
 {
 tg->loadItems = loadGenePredWithConfiguredName;
 tg->itemName = gencodePilotGeneName;
 }
 
 static Color gencodeIntronPilotColorItem(struct track *tg, void *item, struct hvGfx *hvg)
 /* Return color of ENCODE gencode intron track item.  For ENCODE pilot tracks only.
  * Use recommended color palette pantone colors (level 4) for red, green, blue.*/
 {
 struct gencodeIntron *intron = (struct gencodeIntron *)item;
 
 if (sameString(intron->status, "not_tested"))
     return hvGfxFindColorIx(hvg, 214,214,216);       /* light grey */
 if (sameString(intron->status, "RT_negative"))
     return hvGfxFindColorIx(hvg, 145,51,56);       /* red */
 if (sameString(intron->status, "RT_positive") ||
         sameString(intron->status, "RACE_validated"))
     return hvGfxFindColorIx(hvg, 61,142,51);       /* green */
 if (sameString(intron->status, "RT_wrong_junction"))
     return getOrangeColor(hvg);                 /* orange */
 if (sameString(intron->status, "RT_submitted"))
     return hvGfxFindColorIx(hvg, 102,109,112);       /* grey */
 return hvGfxFindColorIx(hvg, 214,214,216);       /* light grey */
 }
 
 static void gencodeIntronPilotLoadItems(struct track *tg)
 /* Load up track items.  For ENCODE pilot tracks only. */
 {
 bedLoadItem(tg, tg->table, (ItemLoader)gencodeIntronLoad);
 }
 
 static void gencodeIntronPilotMethods(struct track *tg)
 /* Load up custom methods for ENCODE Gencode intron validation track.
  * For ENCODE pilot tracks only. */
 {
 tg->loadItems = gencodeIntronPilotLoadItems;
 tg->itemColor = gencodeIntronPilotColorItem;
 }
 
 static void gencodePilotRaceFragsMethods(struct track *tg)
 /* Load up custom methods for ENCODE Gencode RACEfrags track.  For ENCODE
  * pilot tracks only. */
 {
 tg->loadItems = loadGenePred;
 tg->subType = lfNoIntronLines;
 }
 
 static void registerPilotTrackHandlers()
 /* register track handlers for pilot GENCODE tracks */
 {
 // hg16 only
 registerTrackHandler("encodeGencodeGene", gencodePilotGeneMethods);
 registerTrackHandler("encodeGencodeIntron", gencodeIntronPilotMethods);
 
 // hg17 only
 registerTrackHandler("encodeGencodeGeneJun05", gencodePilotGeneMethods);
 registerTrackHandler("encodeGencodeIntronJun05", gencodeIntronPilotMethods);
 registerTrackHandler("encodeGencodeGeneOct05", gencodePilotGeneMethods);
 registerTrackHandler("encodeGencodeIntronOct05", gencodeIntronPilotMethods);
 registerTrackHandler("encodeGencodeGeneMar07", gencodePilotGeneMethods);
 registerTrackHandler("encodeGencodeGenePolyAMar07", bed9Methods);
 registerTrackHandler("encodeGencodeRaceFrags", gencodePilotRaceFragsMethods);
 }
 
 
 void gencodeRegisterTrackHandlers()
 /* register track handlers for GENCODE tracks */
 {
 registerProductionTrackHandlers();
 registerPilotTrackHandlers();
 }