afa49f8318fdcd16205bc6cbc55d293d208fc5bd angie Tue May 10 11:37:29 2011 -0700 Feature #3711 bugfix: handle 0 or 1 items correctly in hacTree andVCF track handler's haplotype clustering. diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c index de722ff..02c2a01 100644 --- src/hg/hgTracks/vcfTrack.c +++ src/hg/hgTracks/vcfTrack.c @@ -238,30 +238,34 @@ dy2 = dyStringNew(0); } hapClusterToString(c1, dy1, helper->len); hapClusterToString(c2, dy2, helper->len); return strcmp(dy1->string, dy2->string); } void rSetGtHapOrder(struct hacTree *ht, unsigned short *gtHapOrder, unsigned short *retGtHapEnd) /* Traverse hacTree and build an ordered array of genotype + haplotype indices. */ { if (ht->left == NULL && ht->right == NULL) { struct hapCluster *c = (struct hapCluster *)ht->itemOrCluster; gtHapOrder[(*retGtHapEnd)++] = c->gtHapIx; } +else if (ht->left == NULL) + rSetGtHapOrder(ht->right, gtHapOrder, retGtHapEnd); +else if (ht->right == NULL) + rSetGtHapOrder(ht->left, gtHapOrder, retGtHapEnd); else { struct hapCluster *cL = (struct hapCluster *)ht->left->itemOrCluster; struct hapCluster *cR = (struct hapCluster *)ht->right->itemOrCluster; if (cL->leafCount >= cR->leafCount) { rSetGtHapOrder(ht->left, gtHapOrder, retGtHapEnd); rSetGtHapOrder(ht->right, gtHapOrder, retGtHapEnd); } else { rSetGtHapOrder(ht->right, gtHapOrder, retGtHapEnd); rSetGtHapOrder(ht->left, gtHapOrder, retGtHapEnd); } } @@ -440,30 +444,32 @@ dyStringPrintf(dy, "%s/%s:%d %s/%s:%d %s/%s:%d", rec->ref, rec->ref, gtRefRefCount, rec->ref, altAlleles[0], gtRefAltCount, altAlleles[0], altAlleles[0], gtAltAltCount); if (gtOtherCount > 0) dyStringPrintf(dy, " other:%d", gtOtherCount); return dy->string; } static void vcfHapClusterDraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Split samples' chromosomes (haplotypes), cluster them by center-weighted * alpha similarity, and draw in the order determined by clustering. */ { const struct vcfFile *vcff = tg->extraUiData; +if (vcff->records == NULL) + return; unsigned short gtHapEnd = 0; unsigned short *gtHapOrder = clusterChroms(vcff, >HapEnd); struct dyString *tmp = dyStringNew(0); struct vcfRecord *rec; const int lineHeight = tg->lineHeight; const int itemHeight = tg->heightPer; const double scale = scaleForPixels(width); for (rec = vcff->records; rec != NULL; rec = rec->next) { dyStringClear(tmp); dyStringAppend(tmp, rec->alt); char *altAlleles[256]; int altCount = chopCommas(tmp->string, altAlleles); int x1 = round((double)(rec->chromStart-winStart)*scale) + xOff; int x2 = round((double)(rec->chromEnd-winStart)*scale) + xOff; @@ -482,30 +488,32 @@ hvg, x1, y, w, itemHeight, lineHeight); } mapBoxHgcOrHgGene(hvg, rec->chromStart, rec->chromEnd, x1, yOff, w, tg->height, tg->track, rec->name, gtSummaryString(rec, altAlleles, altCount), NULL, TRUE, NULL); } // left labels? } static int vcfHapClusterTotalHeight(struct track *tg, enum trackVisibility vis) /* Return height of haplotype graph (2 * #samples * lineHeight); * 2 because we're assuming diploid genomes here, no XXY, tetraploid etc. */ { // Should we make it single-height when on chrY? const struct vcfFile *vcff = tg->extraUiData; +if (vcff->records == NULL) + return 0; int ploidy = 2; tg->height = ploidy * vcff->genotypeCount * tg->lineHeight; return tg->height; } static char *vcfHapClusterTrackName(struct track *tg, void *item) /* If someone asks for itemName/mapItemName, just send name of track like wiggle. */ { return tg->track; } static void vcfHapClusterOverloadMethods(struct track *tg, struct vcfFile *vcff) /* If we confirm at load time that we can draw a haplotype graph, use * this to overwrite the methods for the rest of execution: */ {