aa76ee6119d9baf92a033231d898cc31967846b5
tdreszer
  Tue Feb 1 17:32:37 2011 -0800
Support for extraFields trackDb setting for bed items
diff --git src/hg/hgc/hgc.c src/hg/hgc/hgc.c
index e6d51c4..62b2091 100644
--- src/hg/hgc/hgc.c
+++ src/hg/hgc/hgc.c
@@ -756,30 +756,31 @@
     char *label = "Item", *tdbLabel = NULL;
     if (tdb && ((tdbLabel = trackDbSetting(tdb, "bedNameLabel")) != NULL))
 	label = tdbLabel;
     printf("<B>%s:</B> %s<BR>\n", label, bed->name);
     }
 if (bedSize >= 5)
     {
     if (!tdb || !trackDbSetting(tdb, "noScoreFilter"))
 	printf("<B>Score:</B> %d<BR>\n", bed->score);
     }
 if (bedSize >= 6)
    {
    strand = bed->strand;
    }
 printPos(bed->chrom, bed->chromStart, bed->chromEnd, strand, TRUE, bed->name);
+
 }
 
 void interactionPrintPos( struct bed *bed, int bedSize, struct trackDb *tdb)
 /* Print first bedSize fields of a bed type structure in
  * standard format. */
 {
 
 if (bed->blockCount == 2)
     {
     printf("<B>Intrachromosomal interaction:</B> <br>\n");
     printf("<B>Positions:</B><br> ");
     printf("<A HREF=\"%s&db=%s&position=%s%%3A%d-%d\">",
 	   hgTracksPathAndSettings(), database, bed->chrom, 
 	   bed->chromStarts[0]+bed->chromStart, 
 	   bed->chromStarts[0]+bed->chromStart + bed->blockSizes[0]);
@@ -1373,30 +1374,101 @@
 		char dbOnly[4096];
 
 		diff = comp2->start - (comp1->start + comp1->size);
 
 		safef(dbOnly, sizeof(dbOnly), "%s", comp1->src);
 		chopPrefix(dbOnly);
 		printf("%-20s %d\n",hOrganism(dbOnly), diff);
 		}
 
 	    printf("<BR>");
 	    }
 	}
     }
 }
 
+int extraFieldsPrint(struct trackDb *tdb,struct sqlResult *sr,char **row)
+// Any extra fields defined in trackDb.  Retruns number of extra fields actually printed
+{
+// Additional fields requested in trackDb?
+char *fields = trackDbSetting(tdb, "extraFields"); // showFileds pValue=P_Value qValue=qValue
+if (fields == NULL)
+    return 0;
+
+char *historicalRecord = fields;
+int count = 0;
+char *field = cloneNextWord(&fields); // fields not harmed but pointer advanced
+while(field != NULL)
+    {
+    // parse field as "pValue=[f]P_Value" inot field="pValue" and label="[f]P_Value"
+    char *label = field;
+    char *equal = strchr(field,'=');
+    if (equal != NULL)
+        {
+        *equal = '\0';
+        label = equal + 1;
+        assert(*label!='\0');
+        }
+
+    // We have a field requested but is it in the table?
+    int ix = sqlFieldColumn(sr, field);
+    if (ix == -1)
+        warn("trackDb setting [extraFields %s] could not find %s in %s.\n", historicalRecord, field,tdb->table);
+    else
+        {
+        // parse label "[f]P_Value" into label="P Value" and type=float
+        char *type  = "string";
+        if (*label == '[')
+            {
+            if (startsWith("[i",label))
+                type = "integer";
+            else if (startsWith("[f",label))
+                type = "float";
+            label = strchr(label,']');
+            assert(label != NULL);
+            label += 1;
+            }
+
+        // Print as table rows
+        if(count == 0)
+            printf("<br><table>");
+        printf("<tr><td><B>%s:</B></td>", strSwapChar(label,'_',' ')); // No '_' in label
+        if (sameString(type,"integer"))
+            {
+            long long val = sqlLongLong(row[ix]);
+            printf("<td>%lld</td></tr>\n", val);
+            }
+        else if (sameString(type,"float"))
+            {
+            double val = sqlDouble(row[ix]);
+            printf("<td>%g</td></tr>\n", val);
+            }
+        else
+            printf("<td>%s</td></tr>\n", row[ix]);
+        count++;
+        }
+
+    // free mem and move to next field
+    freeMem(field);
+    field = cloneNextWord(&fields); // around we go
+    }
+if(count > 0)
+    printf("</table>\n");
+
+return count;
+}
+
 void genericBedClick(struct sqlConnection *conn, struct trackDb *tdb,
 		     char *item, int start, int bedSize)
 /* Handle click in generic BED track. */
 {
 char table[64];
 boolean hasBin;
 struct bed *bed;
 char query[512];
 struct sqlResult *sr;
 char **row;
 boolean firstTime = TRUE;
 char *escapedName = sqlEscapeString(item);
 
 hFindSplitTable(database, seqName, tdb->table, table, &hasBin);
 if (bedSize <= 3)
@@ -1413,30 +1485,32 @@
     }
 sr = sqlGetResult(conn, query);
 while ((row = sqlNextRow(sr)) != NULL)
     {
     if (firstTime)
 	firstTime = FALSE;
     else
 	htmlHorizontalLine();
     bed = bedLoadN(row+hasBin, bedSize);
     if ((tdb->type != NULL) && sameString(tdb->type, "interaction"))
 	{
 	interactionPrintPos( bed, bedSize, tdb);
 	}
     else
 	bedPrintPos(bed, bedSize, tdb);
+
+    extraFieldsPrint(tdb,sr,row);
     // check for seq1 and seq2 in columns 7+8 (eg, pairedTagAlign)
     char *setting = trackDbSetting(tdb, BASE_COLOR_USE_SEQUENCE);
     if (bedSize == 6 && setting && sameString(setting, "seq1Seq2"))
 	printf("<br><B>Sequence 1:</B> %s<br><B>Sequence 2:</B> %s<br>\n",row[hasBin+6], row[hasBin+7]);
     printCompareGenomeLinks(tdb,bed->name);
     }
 sqlFreeResult(&sr);
 getBedTopScorers(conn, tdb, table, item, start, bedSize);
 }
 
 #define INTRON 10
 #define CODINGA 11
 #define CODINGB 12
 #define UTR5 13
 #define UTR3 14