9cc2351f465f585965408ff48fea2ad79a1aaa91
markd
  Mon Jun 6 17:40:11 2011 -0700
meger of GENCODE V7 tracks
diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index 43adb85..392fa0e 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -4189,99 +4189,185 @@
 strncpy(abbrev, full, sizeof(abbrev));
 abbr(abbrev, "00000");
 abbr(abbrev, "0000");
 abbr(abbrev, "000");
 abbr(abbrev, "ctg");
 abbr(abbrev, "Affy.");
 return abbrev;
 }
 
 void genieAltMethods(struct track *tg)
 /* Make track of full length mRNAs. */
 {
 tg->itemName = genieName;
 }
 
-boolean genePredClassFilter(struct track *tg, void *item)
-/* Returns true if an item should be added to the filter. */
-{
-struct linkedFeatures *lf = item;
-char *classType = NULL;
-enum acemblyOptEnum ct;
-struct sqlConnection *conn = NULL;
-char query[1024];
-char **row = NULL;
-struct sqlResult *sr;
-char *classTable = NULL;
-/* default is true then for no filtering */
-boolean sameClass = TRUE;
-classTable = trackDbSetting(tg->tdb, GENEPRED_CLASS_TBL);
-
-if (classTable != NULL && hTableExists(database, classTable))
-    {
-    filterBy_t *filterBySet = filterBySetGet(tg->tdb,cart,NULL);
-    if(filterBySet != NULL)
+static struct dyString *genePredClassFilterBySetQuery(struct track *tg, char *classTable,
+                                                      filterBy_t *filterBySet, struct linkedFeatures *lf)
+/* construct the query for a standard genePred class filterBtSet */
         {
-        query[0] = 0;
-        boolean passesThroughFilter = FALSE;
         char *clause = filterBySetClause(filterBySet);
         if(clause == NULL)
-            passesThroughFilter = TRUE;
+    return NULL;
+
+// don't care about a column value here, just if it exists, so get a constant
+char *nameCol = trackDbSettingOrDefault(tg->tdb, GENEPRED_CLASS_NAME_COLUMN, GENEPRED_CLASS_NAME_COLUMN_DEFAULT);
+struct dyString *dyQuery = dyStringCreate("select 1 from %s where %s = \"%s\" and ", classTable, nameCol, lf->name);
+dyStringAppend(dyQuery, clause);
+freeMem(clause);
+return dyQuery;
+}
+
+static void gencodeFilterByMethodChoice(struct dyString *dyClause, char *choice)
+/* add compared for a choice for special case of GENCODE transcript method. */
+{
+if (sameString(choice, "manual"))
+    dyStringAppend(dyClause, "(transSrc.source like \"%havana%\")");
+else if (sameString(choice, "automatic"))
+    dyStringAppend(dyClause, "(transSrc.source like \"%ensembl%\")");
+else if (sameString(choice, "manual_only"))
+    dyStringAppend(dyClause, "(transSrc.source not like \"%havana%\")");
+else if (sameString(choice, "automatic_only"))
+    dyStringAppend(dyClause, "(transSrc.source not like \"%ensembl%\")");
         else
+    errAbort("BUG: filterByMethodChoice missing choice: \"%s\"", choice);
+}
+
+static char *gencodeFilterByMethod(filterBy_t *filterBy)
             {
-            struct dyString *dyQuery = dyStringCreate("select class from %s where name = \"%s\" and ", classTable, lf->name);
-            dyStringAppend(dyQuery, clause);
+if ((filterBy->slChoices == NULL) || (slNameInList(filterBy->slChoices,"All")))
+    return NULL;
+
+struct dyString *clause = newDyString(256);
+struct slName *slChoice = NULL;
+dyStringAppend(clause, "(transSrc.transcriptId = attrs.transcriptId) and ");
+boolean first = TRUE;
+for(slChoice = filterBy->slChoices; slChoice != NULL; slChoice = slChoice->next)
+    {
+    if(!first)
+        dyStringPrintf(clause, " or ");
+    first = FALSE;
+    gencodeFilterByMethodChoice(clause, slChoice->name);
+    }
+return dyStringCannibalize(&clause);
+}
 
+static void gencodeFilterBy(filterBy_t *filterBy, struct dyString *where)
+/* handle adding on filterBy clause for gencode */
+{
+char *clause;
+if (sameString(filterBy->column, "transcriptMethod"))
+    clause = gencodeFilterByMethod(filterBy);
+else
+    clause = filterByClause(filterBy);
+if (clause != NULL)
+    {
+    dyStringPrintf(where, " and (%s)", clause);
             freeMem(clause);
+    }
+}
 
-            conn = hAllocConn(database);
-            sr = sqlGetResult(conn, dyStringCannibalize(&dyQuery));
-            if ((row = sqlNextRow(sr)) != NULL)
-                passesThroughFilter = TRUE;
-            sqlFreeResult(&sr);
-            hFreeConn(&conn);
+static struct dyString *gencodeFilterBySetQueryWhere(struct track *tg, filterBy_t *filterBySet)
+/* build where clause based on filters, or NULL if none */
+{
+struct dyString *where = dyStringNew(0);
+filterBy_t *filterBy;
+for (filterBy = filterBySet;filterBy != NULL; filterBy = filterBy->next)
+    gencodeFilterBy(filterBy, where);
+if (dyStringLen(where) == 0)
+    dyStringFree(&where);
+return where;
             }
-        filterBySetFree(&filterBySet);
+
+static struct dyString *gencodeFilterBySetQuery(struct track *tg, filterBy_t *filterBySet, struct linkedFeatures *lf)
+/* construct the query for GENCODE filterBySet */
+{
+struct dyString *where = gencodeFilterBySetQueryWhere(tg, filterBySet);
+if (where == NULL)
+    return NULL;
+char *attrsTbl = trackDbRequiredSetting(tg->tdb, "wgEncodeGencodeAttrs");
+char *srcTbl = trackDbRequiredSetting(tg->tdb, "wgEncodeGencodeTranscriptSource");
+struct dyString *dyQuery = dyStringCreate("select 1 from %s attrs, %s transSrc where (attrs.transcriptId = \"%s\") %s", attrsTbl, srcTbl, lf->name, where->string);
+dyStringFree(&where);
+return dyQuery;
+}
+
+static boolean genePredClassFilterBySet(struct track *tg, char *classTable,
+                                        filterBy_t *filterBySet, struct linkedFeatures *lf)
+/* Check if an item passes a filterBySet filter  */
+{
+struct dyString *dyQuery = NULL;
+if (trackDbSetting(tg->tdb, "wgEncodeGencodeVersion") != NULL)
+    {
+    if (startsWith("wgEncodeGencodeBasic", tg->tdb->track)
+        || startsWith("wgEncodeGencodeFull", tg->tdb->track)
+        || startsWith("wgEncodeGencodePseudoGene", tg->tdb->track))
+        dyQuery = gencodeFilterBySetQuery(tg, filterBySet, lf);
+    }
+else
+    dyQuery = genePredClassFilterBySetQuery(tg, classTable, filterBySet, lf);
+if (dyQuery == NULL)
+    return TRUE;
+
+struct sqlConnection *conn = hAllocConn(database);
+boolean passesThroughFilter = sqlQuickNum(conn, dyQuery->string);
+dyStringFree(&dyQuery);
+hFreeConn(&conn);
         return passesThroughFilter;
         }
 
-    if (sameString(tg->table, "acembly"))
+static boolean genePredClassFilterAcembly(struct track *tg, char *classTable,
+                                          struct linkedFeatures *lf)
+/* Check if an item passes a filterBySet filter  */
         {
 	char *classString = addSuffix(tg->track, ".type");
-        classType = cartUsualString(cart, classString, acemblyEnumToString(0));
+char *classType = cartUsualString(cart, classString, acemblyEnumToString(0));
 	freeMem(classString);
-        ct = acemblyStringToEnum(classType);
+enum acemblyOptEnum ct = acemblyStringToEnum(classType);
         if (ct == acemblyAll)
-            return sameClass;
-        }
-    else if (classType == NULL) // FIXME: Bug? All but acembly drop out here
         return TRUE;
-
-    conn = hAllocConn(database);
+struct sqlConnection *conn = hAllocConn(database);
+char query[1024];
     safef(query, sizeof(query),
-         "select class from %s where name = \"%s\"", classTable, lf->name);
-    sr = sqlGetResult(conn, query);
-    if ((row = sqlNextRow(sr)) != NULL)
+      "select 1 from %s where (name = \"%s\") and (class = \"%s\")", classTable, lf->name, classType);
+boolean passesThroughFilter = sqlQuickNum(conn, query);
+hFreeConn(&conn);
+return passesThroughFilter;
+}
+
+boolean genePredClassFilter(struct track *tg, void *item)
+/* Returns true if an item should be added to the filter. */
+{
+struct linkedFeatures *lf = item;
+char *classTable = trackDbSetting(tg->tdb, GENEPRED_CLASS_TBL);
+
+if (classTable != NULL && hTableExists(database, classTable))
         {
-        /* check if this is the same as the class required */
-        if (!sameString(row[0], classType))
-            sameClass = FALSE;
+    filterBy_t *filterBySet = filterBySetGet(tg->tdb,cart,NULL);
+    if (filterBySet != NULL)
+        {
+        boolean passesThroughFilter = genePredClassFilterBySet(tg, classTable, filterBySet, lf);
+        filterBySetFree(&filterBySet);
+        return passesThroughFilter;
         }
-    sqlFreeResult(&sr);
+
+    if (sameString(tg->table, "acembly"))
+        {
+        return genePredClassFilterAcembly(tg, classTable, lf);
     }
-hFreeConn(&conn);
-return sameClass;
+    }
+return TRUE;
 }
 
 void loadGenePredWithName2(struct track *tg)
 /* Convert gene pred in window to linked feature. Include alternate name
  * in "extra" field (usually gene name)*/
 {
 struct sqlConnection *conn = hAllocConn(database);
 tg->items = connectedLfFromGenePredInRangeExtra(tg, conn, tg->table,
                                         chromName, winStart, winEnd, TRUE);
 hFreeConn(&conn);
 /* filter items on selected criteria if filter is available */
 filterItems(tg, genePredClassFilter, "include");
 }
 
 void lookupKnownNames(struct linkedFeatures *lfList)
@@ -9966,86 +10052,90 @@
 /* Convert gene pred info in window to linked feature. Include name
  * in "extra" field (gene name, accession, or both, depending on UI) */
 {
 char *geneLabel;
 boolean useGeneName, useAcc;
 struct linkedFeatures *lf;
 
 geneLabel = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, "label","gene");
 useGeneName = sameString(geneLabel, "gene") || sameString(geneLabel, "name") || sameString(geneLabel, "both");
 useAcc = sameString(geneLabel, "accession") || sameString(geneLabel, "both");
 
 loadGenePredWithName2(tg);
 for (lf = tg->items; lf != NULL; lf = lf->next)
     {
     struct dyString *name = dyStringNew(SMALLDYBUF);
-    if (useGeneName && lf->extra)
+    if (useGeneName && !isEmpty((char*)lf->extra))
+        {
         dyStringAppend(name, lf->extra);
-    if (useGeneName && useAcc)
+        if (useAcc)
         dyStringAppendC(name, '/');
+        }
     if (useAcc)
         dyStringAppend(name, lf->name);
     lf->extra = dyStringCannibalize(&name);
     }
 }
 
 Color genePredItemAttrColor(struct track *tg, void *item, struct hvGfx *hvg)
 /* Return color to draw a genePred in based on looking it up in a itemAttr
  * table. */
 {
 struct linkedFeatures *lf = item;
 if (lf->itemAttr != NULL)
     return hvGfxFindColorIx(hvg, lf->itemAttr->colorR, lf->itemAttr->colorG, lf->itemAttr->colorB);
 else
     return tg->ixColor;
 }
 
 Color genePredItemClassColor(struct track *tg, void *item, struct hvGfx *hvg)
 /* Return color to draw a genePred based on looking up the gene class */
 /* in an itemClass table. */
 {
 char *geneClasses = trackDbSetting(tg->tdb, GENEPRED_CLASS_VAR);
 char *gClassesClone = NULL;
 int class, classCt = 0;
 char *classes[20];
 char gClass[SMALLBUF];
 char *classTable = trackDbSetting(tg->tdb, GENEPRED_CLASS_TBL);
+char *nameCol = trackDbSettingOrDefault(tg->tdb, GENEPRED_CLASS_NAME_COLUMN, GENEPRED_CLASS_NAME_COLUMN_DEFAULT);
+char *classCol = trackDbSettingOrDefault(tg->tdb, GENEPRED_CLASS_CLASS_COLUMN, GENEPRED_CLASS_CLASS_COLUMN_DEFAULT);
 struct linkedFeatures *lf = item;
 struct sqlConnection *conn = hAllocConn(database);
 struct sqlResult *sr;
 char **row = NULL;
 char query[256];
 boolean found = FALSE;
 char *colorString = NULL, *colorClone = NULL;
 struct rgbColor gClassColor;
 int color = tg->ixColor; /* default color in trackDb */
 int size = 3;
 char *rgbVals[5];
 char *sep = ",";
 
 if (geneClasses == NULL)
    errAbort(
       "Track %s missing required trackDb setting: geneClasses", tg->track);
 if (geneClasses)
    {
    gClassesClone = cloneString(geneClasses);
    classCt = chopLine(gClassesClone, classes);
    }
 if (hTableExists(database, classTable))
    {
    safef(query, sizeof(query),
-        "select class from %s where name = \"%s\"", classTable, lf->name);
+         "select %s from %s where %s = \"%s\"", classCol, classTable, nameCol, lf->name);
    sr = sqlGetResult(conn, query);
    if ((row = sqlNextRow(sr)) != NULL)
         {
         /* scan through groups to find a match */
         for (class = 0; class < classCt; class++)
            {
            if (sameString(classes[class], row[0]))
            /* get color from trackDb settings hash */
               {
               found = TRUE;
               safef(gClass, sizeof(gClass), "%s%s", GENEPRED_CLASS_PREFIX, classes[class]);
               colorString = trackDbSetting(tg->tdb, gClass);
               if (!colorString)
                   found = FALSE;
               break;
@@ -12619,30 +12709,36 @@
 registerTrackHandler("mcFolds", rnaSecStrMethods);
 registerTrackHandler("rnaEditFolds", rnaSecStrMethods);
 registerTrackHandler("altSpliceFolds", rnaSecStrMethods);
 registerTrackHandler("chimpSimpleDiff", chimpSimpleDiffMethods);
 registerTrackHandler("tfbsCons", tfbsConsMethods);
 registerTrackHandler("tfbsConsSites", tfbsConsSitesMethods);
 registerTrackHandler("pscreen", simpleBedTriangleMethods);
 registerTrackHandler("dless", dlessMethods);
 registerTrackHandler("jaxAllele", jaxAlleleMethods);
 registerTrackHandler("jaxPhenotype", jaxPhenotypeMethods);
 registerTrackHandler("jaxAlleleLift", jaxAlleleMethods);
 registerTrackHandler("jaxPhenotypeLift", jaxPhenotypeMethods);
 /* ENCODE related */
 registerTrackHandlerOnFamily("wgEncodeGencode", gencodeGeneMethods);
 registerTrackHandlerOnFamily("wgEncodeSangerGencode", gencodeGeneMethods);
+registerTrackHandler("wgEncodeGencodeV7", gencodeGeneMethods);
+registerTrackHandler("wgEncodeGencodeBasicV7", gencodeGeneMethods);
+registerTrackHandler("wgEncodeGencodeFullV7", gencodeGeneMethods);
+registerTrackHandler("wgEncodeGencodePseudoGeneV7", gencodeGeneMethods);
+registerTrackHandler("wgEncodeGencode2wayConsPseudoV7", gencodeGeneMethods);
+registerTrackHandler("wgEncodeGencodePolyaV7", gencodeGeneMethods);
 registerTrackHandlerOnFamily("wgEncodeSangerGencodeGencodeManual20081001", gencodeGeneMethods);
 registerTrackHandlerOnFamily("wgEncodeSangerGencodeGencodeAuto20081001", gencodeGeneMethods);
 registerTrackHandlerOnFamily("encodeGencodeGene", gencodeGeneMethods);
 registerTrackHandlerOnFamily("encodeGencodeGeneJun05", gencodeGeneMethods);
 registerTrackHandlerOnFamily("encodeGencodeGeneOct05", gencodeGeneMethods);
 registerTrackHandlerOnFamily("encodeGencodeGeneMar07", gencodeGeneMethods);
 registerTrackHandler("encodeGencodeIntron", gencodeIntronMethods);
 registerTrackHandler("encodeGencodeIntronJun05", gencodeIntronMethods);
 registerTrackHandler("encodeGencodeIntronOct05", gencodeIntronMethods);
 registerTrackHandlerOnFamily("encodeGencodeRaceFrags", gencodeRaceFragsMethods);
 registerTrackHandler("affyTxnPhase2", affyTxnPhase2Methods);
 registerTrackHandler("gvPos", gvMethods);
 registerTrackHandlerOnFamily("pgSnp", pgSnpMethods);
 registerTrackHandlerOnFamily("pgSnpHgwdev", pgSnpMethods);
 registerTrackHandlerOnFamily("pgPop", pgSnpMethods);