src/hg/hgTracks/bedTrack.c 1.10
1.10 2009/05/24 09:10:38 mikep
Added pairedTagAlign baseColor option controlled by 'seq1Seq2' option to baseColorUseSequence
Index: src/hg/hgTracks/bedTrack.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/hg/hgTracks/bedTrack.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -b -B -U 4 -r1.9 -r1.10
--- src/hg/hgTracks/bedTrack.c 22 May 2009 19:26:08 -0000 1.9
+++ src/hg/hgTracks/bedTrack.c 24 May 2009 09:10:38 -0000 1.10
@@ -9,8 +9,10 @@
#include "bigBed.h"
#include "hgTracks.h"
#include "cds.h"
+#define SEQ_DELIM '~'
+
static char *bbiNameFromTable(struct sqlConnection *conn, char *table)
/* Return file name from little table. */
{
char query[256];
@@ -33,8 +35,21 @@
bbiFileClose(&bbi);
return result;
}
+struct bed *bedLoadPairedTagAlign(char **row)
+/* Load first six fields of bed.
+ * Add ~seq1~seq2 to end of name
+ * Then remove the sequence to extra field when we convert to linkedFeature */
+{
+char buf[1024];
+struct bed *ret = bedLoad6(row);
+safef(buf, sizeof(buf), "%s%c%s%c%s", ret->name, SEQ_DELIM, row[6], SEQ_DELIM, row[7]);
+freez(&(ret->name));
+ret->name = cloneString(buf);
+return ret;
+}
+
void loadSimpleBed(struct track *tg)
/* Load the items in one track - just move beds in
* window... */
{
@@ -59,8 +74,13 @@
loader = bedLoad5;
else
loader = bedLoad6;
+// pairedTagAlign loader is required for base coloring using sequence from seq1 & seq2
+if ((setting = trackDbSetting(tg->tdb, BASE_COLOR_USE_SEQUENCE))
+ && sameString(setting, "seq1Seq2"))
+ loader = bedLoadPairedTagAlign;
+
/* limit to a specified count of top scoring items.
* If this is selected, it overrides selecting item by specified score */
if ((setting = trackDbSettingClosestToHome(tg->tdb, "filterTopScorers")) != NULL)
{
@@ -627,34 +647,72 @@
tg->labelNextPrevItem = linkedFeaturesLabelNextPrevItem;
tg->freeItems = freeSimpleBed;
}
-struct linkedFeatures *simpleBedToLinkedFeatures(struct bed *b, int bedFields, boolean everyBase)
+void addSimpleFeatures(struct simpleFeature **pSfList, int start, int end, int qStart, int stepSize)
+{
+int s;
+struct simpleFeature *sf;
+for (s = start ; s < end ; s += stepSize)
+ {
+ AllocVar(sf);
+ sf->start = s;
+ sf->end = sf->start + stepSize;
+ sf->qStart = qStart + (s - start);
+ sf->qEnd = sf->qStart + stepSize;
+ slAddHead(pSfList, sf);
+ }
+}
+
+struct linkedFeatures *simpleBedToLinkedFeatures(struct bed *b, int bedFields,
+ boolean everyBase, boolean paired)
/* Create a linked feature from a single bed item
* Any bed fields past the 6th field (strand) will be ignored
* Make one simpleFeature for every base of the bed if everyBase is TRUE,
* otherwise it will contain a single 'exon' corresponding to the bed (start,end)
* Dont free the bed as a pointer to each item is stored in lf->original
+ * If paired then need to strip ~seq1~seq2 from name and set it as DNA in lf->extra
+ * and treat bed as 2-exon bed.
*/
{
struct linkedFeatures *lf = NULL;
+int stepSize;
if (b)
{
AllocVar(lf);
lf->start = lf->tallStart = b->chromStart;
lf->end = lf->tallEnd = b->chromEnd;
- struct simpleFeature *sf;
- int s;
- int stepSize = everyBase ? 1 : lf->end - lf->start;
lf->components = NULL;
- for (s = lf->start ; s < lf->end ; s += stepSize)
+ if (paired)
{
- AllocVar(sf);
- sf->start = s;
- sf->end = sf->start + stepSize;
- sf->qStart = s - lf->start;
- sf->qEnd = sf->qStart + stepSize;
- slAddHead(&lf->components, sf);
+ // Find seq1 & seq2, strip them from the name,
+ // add them as two blocks of simpleFeatures,
+ // concatenate seq1 & seq2 into one dnaSeq,
+ // and store in lf->extra field
+ char *seq2 = strrchr(b->name, SEQ_DELIM);
+ if (!seq2)
+ errAbort("Could not find seq2 in paired sequence");
+ *(seq2++) = '\0';
+ // Find seq1 and strip it from the name
+ char *seq1 = strrchr(b->name, SEQ_DELIM);
+ if (!seq1)
+ errAbort("Could not find seq1 in paired sequence");
+ *(seq1++) = '\0';
+ int l1 = strlen(seq1);
+ int l2 = strlen(seq2);
+ struct dyString *d = dyStringNew(l1+l2+1);
+ dyStringAppend(d, seq1);
+ dyStringAppend(d, seq2);
+ lf->extra = newDnaSeq(dyStringCannibalize(&d), l1+l2, lf->name);
+ stepSize = everyBase ? 1 : l1;
+ addSimpleFeatures(&lf->components, lf->start, lf->start + l1, 0, stepSize);
+ stepSize = everyBase ? 1 : l2;
+ addSimpleFeatures(&lf->components, lf->end - l2, lf->end, l1, stepSize);
+ }
+ else
+ {
+ stepSize = everyBase ? 1 : lf->end - lf->start;
+ addSimpleFeatures(&lf->components, lf->start, lf->end, 0, stepSize);
}
slReverse(&lf->components);
if (bedFields > 3)
safecpy(lf->name, sizeof(lf->name), b->name);
@@ -666,15 +724,16 @@
}
return lf;
}
-struct linkedFeatures *simpleBedListToLinkedFeatures(struct bed *b, int bedFields, boolean everyBase)
+struct linkedFeatures *simpleBedListToLinkedFeatures(struct bed *b, int bedFields,
+ boolean everyBase, boolean paired)
/* Create a list of linked features from a list of beds */
{
struct linkedFeatures *lfList = NULL;
while (b)
{
- slAddHead(&lfList, simpleBedToLinkedFeatures(b, bedFields, everyBase));
+ slAddHead(&lfList, simpleBedToLinkedFeatures(b, bedFields, everyBase, paired));
b = b->next;
}
slReverse(&lfList);
return lfList;
@@ -683,9 +742,16 @@
void loadSimpleBedAsLinkedFeaturesPerBase(struct track *tg)
/* bed list not freed as pointer to it is stored in 'original' field */
{
loadSimpleBed(tg);
-tg->items = simpleBedListToLinkedFeatures(tg->items, tg->bedSize, TRUE);
+tg->items = simpleBedListToLinkedFeatures(tg->items, tg->bedSize, TRUE, FALSE);
+}
+
+void loadPairedTagAlignAsLinkedFeaturesPerBase(struct track *tg)
+/* bed list not freed as pointer to it is stored in 'original' field */
+{
+loadSimpleBed(tg);
+tg->items = simpleBedListToLinkedFeatures(tg->items, tg->bedSize, TRUE, TRUE);
}
Color lfItemColorByStrand(struct track *tg, void *item, struct hvGfx *hvg)
@@ -736,8 +802,12 @@
{
// data must be loaded as bed and converted to linkedFeatures
// to draw each base character must make one simpleFeature per base
linkedFeaturesMethods(track);
+ char *setting = trackDbSetting(tdb, BASE_COLOR_USE_SEQUENCE);
+ if (isNotEmpty(setting) && sameString(setting, "seq1Seq2"))
+ track->loadItems = loadPairedTagAlignAsLinkedFeaturesPerBase;
+ else
track->loadItems = loadSimpleBedAsLinkedFeaturesPerBase;
if (trackDbSetting(tdb, "colorByStrand"))
track->itemColor = lfItemColorByStrand;
}