4c9ae67ea6e03ec3069cea012398793046e9ff2a
giardine
  Tue Sep 21 15:00:29 2010 -0700
Adds new track type bedDetail to custom and resident tracks, also adds pgSnp (personal genome SNPs) as custom track type.  bedDetail is bed4 to bed12, with 2 extra fields for an ID and description for hgc clicks.
diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index 729f15f..1d4e8ec 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -106,6 +106,7 @@
 #include "oreganno.h"
 #include "oregannoUi.h"
 #include "pgSnp.h"
+#include "bedDetail.h"
 #include "bed12Source.h"
 #include "dbRIP.h"
 #include "wikiLink.h"
@@ -9509,6 +9510,20 @@
 hFreeConn(&conn);
 }
 
+void loadPgSnpCt(struct track *tg)
+/* Load up pgSnp (personal genome SNP) type custom tracks */
+{
+char query[256];
+struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
+struct customTrack *ct = tg->customPt;
+char *table = ct->dbTableName;
+safef(query, sizeof(query), "select * from %s where chrom = '%s' and chromStart < %d and chromEnd > %d", table, chromName, winEnd, winStart);
+tg->items = pgSnpLoadByQuery(conn, query);
+/* base coloring/display decision on count of items */
+tg->customInt = slCount(tg->items);
+hFreeConn(&conn);
+}
+
 void pgSnpMapItem(struct track *tg, struct hvGfx *hvg, void *item,
         char *itemName, char *mapItemName, int start, int end, int x, int y, int width, int height)
 /* create a special map box item with different
@@ -10320,6 +10335,118 @@
 */
 }
 
+struct linkedFeatures *bedDetailLoadAsLf (char **row, int rowOffset, int fieldCount, boolean useItemRgb)
+/* load as a linked features track and use default displays */
+{
+struct bed *bedPart = bedLoadN(row+rowOffset, fieldCount);
+struct linkedFeatures *lf;
+if (fieldCount < 12)
+    bed8To12(bedPart);
+lf = lfFromBed(bedPart);
+if (useItemRgb)
+    {            
+    lf->extra = (void *)USE_ITEM_RGB;   /* signal for coloring */
+    lf->filterColor=bedPart->itemRgb;
+    }
+return lf;
+}
+
+struct bed *bedDetailLoadAsBed (char **row, int rowOffset, int fieldCount)
+/* load as a bed track and use default displays */
+{
+return bedLoadN(row+rowOffset, fieldCount);
+}
+
+void loadBedDetailCtSimple(struct track *tg)
+/* Load bedDetails custom track as bed 4-7, other fields are for hgc clicks */
+{
+struct bed *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+int rowOffset = 0;
+struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
+struct customTrack *ct = tg->customPt;
+char *table = ct->dbTableName;
+int fieldCount = ct->fieldCount - 2; /* field count of bed part */
+sr = hRangeQuery(conn, table, chromName, winStart, winEnd, NULL, &rowOffset);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = bedDetailLoadAsBed(row, rowOffset, fieldCount);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+tg->items = list;
+tg->bedSize = fieldCount;
+}
+
+void loadBedDetailSimple(struct track *tg)
+/* Load bedDetails track as bed 4-7, other fields are for hgc clicks */
+{
+struct bed *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+int rowOffset = 0;
+struct sqlConnection *conn = hAllocConn(database);
+char *table = tg->table;
+int bedSize = tg->bedSize; /* count of fields in bed part */
+sr = hRangeQuery(conn, table, chromName, winStart, winEnd, NULL, &rowOffset);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = bedDetailLoadAsBed(row, rowOffset, bedSize);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+tg->items = list;
+}
+
+void loadBedDetailCt(struct track *tg) 
+/* Load bedDetails type track as linked features, other fields are for hgc clicks */
+{
+struct linkedFeatures *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+int rowOffset = 0;
+struct sqlConnection *conn = hAllocConn(CUSTOM_TRASH);
+struct customTrack *ct = tg->customPt;
+char *table = ct->dbTableName;
+int fieldCount = ct->fieldCount - 2; /* field count of bed part */
+boolean useItemRgb = bedItemRgb(ct->tdb);
+sr = hRangeQuery(conn, table, chromName, winStart, winEnd, NULL, &rowOffset);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = bedDetailLoadAsLf(row, rowOffset, fieldCount, useItemRgb);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+tg->items = list;
+//tg->bedSize = fieldCount;
+}
+
+void loadBedDetail(struct track *tg)
+/* Load bedDetails type track as linked features, other fields are for hgc clicks */
+{
+struct linkedFeatures *list = NULL, *el;
+struct sqlResult *sr;
+char **row;
+int rowOffset = 0;
+struct sqlConnection *conn = hAllocConn(database);
+char *table = tg->table;
+int bedSize = tg->bedSize; /* field count of bed part */
+boolean useItemRgb = bedItemRgb(tg->tdb);
+sr = hRangeQuery(conn, table, chromName, winStart, winEnd, NULL, &rowOffset);
+while ((row = sqlNextRow(sr)) != NULL)
+    {
+    el = bedDetailLoadAsLf(row, rowOffset, bedSize, useItemRgb);
+    slAddHead(&list, el);
+    }
+slReverse(&list);
+sqlFreeResult(&sr);
+tg->items = list;
+}
+
 void loadProtVar(struct track *tg)
 /* Load UniProt Variants with labels */
 {
@@ -10382,6 +10509,73 @@
 tg->nextPrevItem = linkedFeaturesLabelNextPrevItem;
 }
 
+char *pgSnpCtMapItemName(struct track *tg, void *item)
+/* Return composite item name for pgSnp custom tracks. */
+{
+struct pgSnp *myItem = item;
+char *itemName = myItem->name;
+static char buf[256];
+if (strlen(itemName) > 0)
+  sprintf(buf, "%s %s", ctFileName, itemName);
+else
+  sprintf(buf, "%s NoItemName", ctFileName);
+return buf;
+}
+
+void bedDetailCtMethods (struct track *tg, struct customTrack *ct)
+/* Load bed detail track from custom tracks as bed 4-12 */
+{
+if (ct != NULL && ct->fieldCount >= (9+2)) /* at least bed9 */
+    {
+    linkedFeaturesMethods(tg);
+    tg->loadItems = loadBedDetailCt;
+    }
+else  /* when in doubt set up as simple bed */
+    { 
+    bedMethods(tg);
+    tg->loadItems = loadBedDetailCtSimple;
+    }
+tg->nextItemButtonable = TRUE;
+tg->customPt = ct;
+tg->canPack = TRUE;
+}
+
+void pgSnpCtMethods (struct track *tg)
+/* Load pgSnp track from custom tracks */
+{
+/* start with the pgSnp methods */
+pgSnpMethods(tg);
+/* loader must access CUSTOM_TRASH */
+tg->loadItems = loadPgSnpCt;
+tg->mapItemName = pgSnpCtMapItemName;
+tg->canPack = TRUE;
+}
+
+void bedDetailMethods (struct track *tg)
+/* Load bed detail track as bed 4-12 */
+{
+struct trackDb *tdb = tg->tdb;
+char *words[3];
+int size, cnt = chopLine(cloneString(tdb->type), words);
+if (cnt > 1) 
+    size = atoi(words[1]) - 2;
+else 
+    size = 4;
+tg->bedSize = size;
+if (size >= 9) /* at least bed9 */
+    {
+    linkedFeaturesMethods(tg);
+    tg->loadItems = loadBedDetail;
+    }
+else  /* when in doubt set up as simple bed */
+    {
+    bedMethods(tg);
+    tg->loadItems = loadBedDetailSimple;
+    }
+tg->nextItemButtonable = TRUE;
+tg->canPack = TRUE;
+}
+
 void protVarMethods (struct track *tg)
 /* name vs id, next items */
 {
@@ -10876,6 +11070,14 @@
     {
     bamMethods(track);
     }
+else if (startsWith(type, "bedDetail"))
+    {
+    bedDetailMethods(track);
+    }
+else if (sameWord(type, "pgSnp"))
+    {
+    pgSnpCtMethods(track);
+    }
 #ifndef GBROWSE
 else if (sameWord(type, "coloredExon"))
     {