6031d05b102c1cb34c9e8394a8acf5809a8eca8f angie Mon Jan 31 16:19:37 2011 -0800 Track #34 (dbVar for human): Added new track type gvf with basichandlers in hgTracks and hgc. dbVar's GVF attributes are recognized, esp. var_type is used to color items, and items are sorted using the Parent keyword so that parents appear immediately before their children, and children are sorted by var_type. Attributes are displayed in hgc; need to do a bit better for the Start_range and End_range (e.g. translate "." to "inner start unknown" etc.). diff --git src/hg/hgTracks/gvfTrack.c src/hg/hgTracks/gvfTrack.c new file mode 100644 index 0000000..12aa558 --- /dev/null +++ src/hg/hgTracks/gvfTrack.c @@ -0,0 +1,122 @@ +/* gvfTrack.c - display variants from GVF (http://www.sequenceontology.org/gvf.html) */ + +#include "common.h" +#include "hgTracks.h" +#include "imageV2.h" +#include "hdb.h" +#include "bed8Attrs.h" + +static Color gvfColor(struct track *tg, void *item, struct hvGfx *hvg) +/* Color item by var_type attribute, according to Deanna Church's document + * SvRepresentation2.doc attached to redmine #34. */ +{ +struct bed8Attrs *gvf = item; +Color dbVarUnknown = hvGfxFindColorIx(hvg, 0xb2, 0xb2, 0xb2); +int ix = stringArrayIx("var_type", gvf->attrTags, gvf->attrCount); +if (ix < 0) + return dbVarUnknown; +char *varType = gvf->attrVals[ix]; +if (sameString(varType, "CNV")) + return MG_BLACK; +else if (sameString(varType, "Gain")) + return hvGfxFindColorIx(hvg, 0xcc, 0x66, 0x00); +else if (sameString(varType, "Loss")) + return hvGfxFindColorIx(hvg, 0x00, 0x00, 0xff); +else if (sameString(varType, "Insertion")) + return hvGfxFindColorIx(hvg, 0xff, 0xcc, 0x00); +else if (sameString(varType, "Complex")) + return hvGfxFindColorIx(hvg, 0x99, 0xcc, 0xff); +else if (sameString(varType, "Unknown")) + return dbVarUnknown; +else if (sameString(varType, "Other")) + return hvGfxFindColorIx(hvg, 0xcc, 0x99, 0xff); +else if (sameString(varType, "Inversion")) + return hvGfxFindColorIx(hvg, 0x99, 0x33, 0xff); // Needs pattern +else if (sameString(varType, "LOH")) + return hvGfxFindColorIx(hvg, 0x00, 0x00, 0xff); // Needs pattern +else if (sameString(varType, "Everted")) + return hvGfxFindColorIx(hvg, 0x66, 0x66, 0x66); // Needs pattern +else if (sameString(varType, "Transchr")) + return hvGfxFindColorIx(hvg, 0xb2, 0xb2, 0xb2); // Plus black vert. bar at broken end +else if (sameString(varType, "UPD")) + return hvGfxFindColorIx(hvg, 0x00, 0xff, 0xff); // Needs pattern +return dbVarUnknown; +} + +// Globals used for sorting: +static struct hash *nameHash = NULL; + +static char *getAttributeVal(const struct bed8Attrs *gvf, char *tag) +/* Return value corresponding to tag or NULL. Don't free result. */ +{ +int ix = stringArrayIx(tag, gvf->attrTags, gvf->attrCount); +if (ix >= 0) + return(gvf->attrVals[ix]); +return NULL; +} + +static int gvfHierCmp(const void *va, const void *vb) +/* Sort GVF so that children follow their parents, and children of the same parent + * are sorted by var_type -- otherwise things are sorted by size,chromStart,name. */ +{ +const struct bed8Attrs *a = *((struct bed8Attrs **)va); +const struct bed8Attrs *b = *((struct bed8Attrs **)vb); +char *aParentName = getAttributeVal(a, "Parent"); +char *bParentName = getAttributeVal(b, "Parent"); +if (bParentName != NULL && sameString(bParentName, a->name)) + return -1; +else if (aParentName != NULL && sameString(aParentName, b->name)) + return 1; +else if (aParentName != NULL && bParentName != NULL && sameString(aParentName, bParentName)) + return strcmp(getAttributeVal(a, "var_type"), getAttributeVal(b, "var_type")); +else + { + const struct bed8Attrs *bedCmpA = a, *bedCmpB = b; + if (aParentName != NULL) + bedCmpA = hashFindVal(nameHash, aParentName); + if (bParentName != NULL) + bedCmpB = hashFindVal(nameHash, bParentName); + // no need to compare chrom here + int diff = ((bedCmpB->chromEnd - bedCmpB->chromStart) - + (bedCmpA->chromEnd - bedCmpA->chromStart)); + if (diff == 0) + { + diff = bedCmpA->chromStart - bedCmpB->chromStart; + if (diff == 0) + diff = strcmp(bedCmpA->name, bedCmpB->name); + } + return diff; + } +} + +static void gvfLoad(struct track *tg) +/* Load GVF items from a bed8Attrs database table. */ +{ +struct sqlConnection *conn = hAllocConn(database); +int rowOffset; +struct sqlResult *sr = hRangeQuery(conn, tg->table, chromName, winStart, winEnd, NULL, &rowOffset); +char **row; +struct bed8Attrs *list = NULL; +// if we someday get dense GVF tracks, might consider upping the default hash size: +if (nameHash == NULL) + nameHash= hashNew(0); +while ((row = sqlNextRow(sr)) != NULL) + { + struct bed8Attrs *gvf = bed8AttrsLoad(row+rowOffset); + slAddHead(&list, gvf); + hashAdd(nameHash, gvf->name, gvf); + } +sqlFreeResult(&sr); +hFreeConn(&conn); +slSort(&list, gvfHierCmp); +tg->items = list; +} + +void gvfMethods(struct track *tg) +/* Load GVF variant data. */ +{ +bedMethods(tg); +tg->canPack = TRUE; +tg->loadItems = gvfLoad; +tg->itemColor = gvfColor; +}