Beispiel #1
0
void bamPairedDrawAt(struct track *tg, void *item, struct hvGfx *hvg, int xOff, int y,
		     double scale, MgFont *font, Color color, enum trackVisibility vis)
/* Draw a bam linked features series item at position. (like linkedFeaturesSeriesDrawAt,
 * but calls bamDrawAt instead of linkedFeaturesDrawAt) */
{
struct linkedFeaturesSeries *lfs = item;
struct linkedFeatures *lf;
int midY = y + (tg->heightPer>>1);
int prevEnd = lfs->start;

if ((lf = lfs->features) == NULL)
    return;
for (lf = lfs->features; lf != NULL; lf = lf->next)
    {

    int x1 = round((double)((int)prevEnd-winStart)*scale) + xOff;
    int x2 = round((double)((int)lf->start-winStart)*scale) + xOff;
    int w = x2-x1;
    if (w > 0)
	hvGfxLine(hvg, x1, midY, x2, midY, color);
    bamDrawAt(tg, lf, hvg, xOff, y, scale, font, color, vis);
    prevEnd = lf->end;
    }
}
Beispiel #2
0
void cytoBandIdeoDraw(struct track *tg,
		      int seqStart, int seqEnd,
		      struct hvGfx *hvg, int xOff, int yOff, int width,
		      MgFont *font, Color color, enum trackVisibility vis)
/* Draw the entire chromosome with a little red box around our
   current position. */
{
double scale = 0;
int xBorder = 4;
int x1, x2;
int yBorder = 0;
int chromSize = hChromSize(database, chromName);
struct cytoBand *cbList = NULL, *cb = NULL;
scale = (double) (width - (2 * xBorder)) / chromSize;

/* Subtrack 10 for the 5 pixels buffer on either side. */
tg->heightPer -= 11;
tg->lineHeight -= 11;

/* Time to draw the bands. */
hvGfxSetClip(hvg, xOff, yOff, width, tg->height);
genericDrawItems(tg, 0, chromSize, hvg, xOff+xBorder, yOff+5, width-(2*xBorder), font, color, tvDense);

x1 = round((winStart)*scale) + xOff + xBorder -1;
x2 = round((winEnd)*scale) + xOff + xBorder -1;
if(x1 >= x2)
    x2 = x1+1;
yBorder = tg->heightPer + 7 + 1;


/* Draw an outline around chromosome for visualization purposes. Helps
 to make the chromosome look better. */
hvGfxLine(hvg, xOff+xBorder, yOff+4, xOff+width-xBorder, yOff+4, MG_BLACK);
hvGfxLine(hvg, xOff+xBorder, yOff+yBorder-3, xOff+width-xBorder, yOff+yBorder-3, MG_BLACK);
hvGfxLine(hvg, xOff+xBorder, yOff+4, xOff+xBorder, yOff+yBorder-3, MG_BLACK);
hvGfxLine(hvg, xOff+width-xBorder, yOff+4, xOff+width-xBorder, yOff+yBorder-3, MG_BLACK);

/* Find and draw the centromere which is defined as the
 two bands with gieStain "acen" */
cbList = tg->items;
for(cb = cbList; cb != NULL; cb = cb->next)
    {
    /* If centromere do some drawing. */
    if(sameString(cb->gieStain, "acen"))
	{
	int cenLeft, cenRight, cenTop, cenBottom;

	/* Get the coordinates of the edges of the centromere. */
	cenLeft = round((cb->chromStart)*scale) + xOff + xBorder;
	cenRight = round((cb->next->chromEnd)*scale) + xOff + xBorder;
	cenTop = yOff+4;
	cenBottom = yOff + yBorder - 3;

	/* Draw centromere itself. */
	hCytoBandDrawCentromere(hvg, cenLeft, cenTop, cenRight - cenLeft,
	     cenBottom-cenTop+1, MG_WHITE, hCytoBandCentromereColor(hvg));
	break;
	}
    }

/* Draw a red box around all positions in windows for this chromName.  
 * Double thick so two pixels thick each. */
struct window *window;
for (window=windows; window; window=window->next)
    {
    if (!sameString(chromName, window->chromName))
	continue;

    x1 = round((window->winStart)*scale) + xOff + xBorder -1;
    x2 = round((window->winEnd)*scale) + xOff + xBorder -1;

    hvGfxBox(hvg, x1, yOff+1,             x2-x1, 2,       MG_RED);
    hvGfxBox(hvg, x1, yOff + yBorder - 1, x2-x1, 2,       MG_RED);
    hvGfxBox(hvg, x1, yOff+1,             2,     yBorder, MG_RED);
    hvGfxBox(hvg, x2, yOff+1,             2,     yBorder, MG_RED);

    }

hvGfxUnclip(hvg);

/* Put back the lineHeight for the track
   now that we are done spoofing tgDrawItems(). */
tg->heightPer += 11;
tg->lineHeight += 11;
}
Beispiel #3
0
static void cgDrawEither(struct track *tg, int seqStart, int seqEnd,
        struct hvGfx *hvg, int xOff, int yOff, int width,
        MgFont *font, Color color, enum trackVisibility vis,
        char *binFileName)
/* Draw chromosome graph - either built in or not. */
{
struct chromGraphSettings *cgs = tg->customPt;
int x,y,lastX=0,lastY=0, llastX = 0, llastY = 0;
int height = tg->height;
int maxGapToFill = cgs->maxGapToFill;
int lastPos = -maxGapToFill-1;
double minVal = cgs->minVal;
double yScale = (height-1)/(cgs->maxVal - minVal);
double xScale = scaleForPixels(width);
Color myColor = cgColorLikeHgGenome(tg, hvg);

/* Draw background lines in full mode. */
if (vis == tvFull && cgs->linesAtCount != 0)
    {
    int i;
    Color lightBlue = hvGfxFindRgb(hvg, &guidelineColor);
    for (i=0; i<cgs->linesAtCount; ++i)
        {
	y = height - 1 - (cgs->linesAt[i] - minVal)*yScale + yOff;
	hvGfxBox(hvg, xOff, y, width, 1, lightBlue);
	}
    }

if (binFileName)
    {
    struct chromGraphBin *cgb = chromGraphBinOpen(binFileName);
    if (chromGraphBinSeekToChrom(cgb, chromName))
	{
	int seqStartMinus = seqStart - cgs->maxGapToFill;
	while (chromGraphBinNextVal(cgb))
	    {
	    int pos = cgb->chromStart;
	    if (pos >= seqStartMinus)
		{
		double val = cgb->val;
		x = (pos - seqStart)*xScale + xOff;
		y = height - 1 - (val - minVal)*yScale + yOff;
		if (x >= xOff)
		    {
		    if (pos - lastPos <= maxGapToFill)
			{
			if (llastX != lastX || llastY != lastY || lastX != x || lastY != y)
			    hvGfxLine(hvg, lastX, lastY, x, y, myColor);
			}
		    else
			hvGfxDot(hvg, x, y, myColor);
		    }
		llastX = lastX;
		llastY = lastY;
		lastX = x;
		lastY = y;
		lastPos = pos;
		if (pos >= seqEnd)
		    break;
		}
	    }
	}
    }
else
    {
    struct sqlConnection *conn = hAllocConn(database);
    char query[512];
    struct sqlResult *sr;
    char **row;
    /* Construct query.  Set up a little more than window so that
     * we can draw connecting lines. */
    sqlSafef(query, sizeof(query),
	"select chromStart,val from %s "
	"where chrom='%s' and chromStart>=%d and chromStart<%d",
	tg->table, chromName,
	seqStart - cgs->maxGapToFill, seqEnd + cgs->maxGapToFill);
    sr = sqlGetResult(conn, query);

    /* Loop through drawing lines from one point to another unless
     * the points are too far apart. */
    while ((row = sqlNextRow(sr)) != NULL)
	{
	int pos = sqlUnsigned(row[0]);
	double val = atof(row[1]);
	x = (pos - seqStart)*xScale + xOff;
	y = height - 1 - (val - minVal)*yScale + yOff;
	if (x >= xOff)
	    {
	    if (pos - lastPos <= maxGapToFill)
		{
		if (llastX != lastX || llastY != lastY || lastX != x || lastY != y)
		    hvGfxLine(hvg, lastX, lastY, x, y, myColor);
		}
	    else
		hvGfxDot(hvg, x, y, myColor);
	    }
	llastX = lastX;
	llastY = lastY;
	lastX = x;
	lastY = y;
	lastPos = pos;
	if (pos >= seqEnd)
	    break;
	}
    sqlFreeResult(&sr);
    hFreeConn(&conn);
    }

/* Do map box */
xOff = hvGfxAdjXW(hvg, xOff, width);

char *encodedTrack = cgiEncode(tg->track);
if (theImgBox && curImgTrack)
    {
    char link[512];     // FIXME: winStart/winEnd are not right when using a portal
    safef(link,sizeof(link),"%s&c=%s&o=%d&t=%d&g=%s", hgcNameAndSettings(),
        chromName, winStart, winEnd, encodedTrack);
#ifdef IMAGEv2_SHORT_MAPITEMS
    if (xOff < insideX && xOff+width > insideX)
        warn("cgDrawEither(%s) map item spanning slices. LX:%d TY:%d RX:%d BY:%d  link:[%s]",
             encodedTrack,xOff, yOff, xOff+width, yOff+height, link);
#endif//def IMAGEv2_SHORT_MAPITEMS
    imgTrackAddMapItem(curImgTrack,link,NULL,xOff,yOff,xOff+width,yOff+height,tg->track);
    }
else
    {
    hPrintf("<AREA SHAPE=RECT COORDS=\"%d,%d,%d,%d\" ", xOff, yOff, xOff+width,
            yOff+height);
    hPrintf("HREF=\"%s&o=%d&t=%d&g=%s&c=%s&l=%d&r=%d&db=%s&pix=%d\">\n",
            hgcNameAndSettings(), winStart, winEnd, encodedTrack, chromName, winStart, winEnd,
            database, tl.picWidth);
    }
}
static void wiggleLinkedFeaturesDraw(struct track *tg, 
	int seqStart, int seqEnd,
struct hvGfx *hvg, int xOff, int yOff, int width, 
	MgFont *font, Color color, enum trackVisibility vis)
	/* Currently this routine is adapted from Terry's 
	* linkedFeatureSeriesDraw() routine.
	* It is called for 'sample' tracks as specified in the trackDb.ra.
	* and it looks at the cart to decide whether to interpolate, fill blocks,
	* and use anti-aliasing.*/
{
	int i;
	struct linkedFeatures *lf;
	struct simpleFeature *sf;
	int y = yOff;
	int heightPer = tg->heightPer;
	int lineHeight = tg->lineHeight;
	int x1,x2;
	boolean isFull = (vis == tvFull);
	Color bColor = tg->ixAltColor;
	double scale = scaleForPixels(width);
	int prevX = -1;
	int gapPrevX = -1;
	double prevY = -1;
	double y1 = -1, y2;
	int ybase;
	int sampleX, sampleY; /* A sample in sample coordinates. 
						  * Sample X coordinate is chromosome coordinate.
						  * Sample Y coordinate is usually 0-1000 */
	int binCount = 1.0/tg->scaleRange;   /* Maximum sample Y coordinate. */
	int bin;	      /* Sample Y coordinates are first converted to
					  * bin coordinates, and then to pixels.  I'm not
					  * totally sure why.  */



	int currentX, currentXEnd, currentWidth;

	int leftSide, rightSide;

	int noZoom = 1;
	enum wiggleOptEnum wiggleType;
	char *interpolate = NULL;
	char *aa = NULL; 
	boolean antiAlias = FALSE;
	int fill; 
	int lineGapSize;
	double min0, max0;

	char o1[128]; /* Option 1 - linear interp */
	char o2[128]; /* Option 2 - anti alias */
	char o3[128]; /* Option 3 - fill */
	char o4[128]; /* Option 4 - minimum vertical range cutoff of plot */	
	char o5[128]; /* Option 5 - maximum vertical range cutoff of plot */
	char o6[128]; /* Option 6 - max gap where interpolation is still done */
	char cartStr[64];
	char *fillStr;

	double hFactor;
	double minRange, maxRange;
	double minRangeCutoff, maxRangeCutoff;


	Color gridColor = hvGfxFindRgb(hvg, &guidelineColor); /* for horizontal lines*/

	lf=tg->items;    
	if(lf==NULL) return;

	//take care of cart options
	safef( o1, 128,"%s.linear.interp", tg->track);
	safef( o2, 128, "%s.anti.alias", tg->track);
	safef( o3, 128,"%s.fill", tg->track);
	safef( o4, 128,"%s.min.cutoff", tg->track);
	safef( o5, 128,"%s.max.cutoff", tg->track);
	safef( o6, 128,"%s.interp.gap", tg->track);

	interpolate = cartUsualString(cart, o1, "Linear Interpolation");
	wiggleType = wiggleStringToEnum(interpolate);
	aa = cartUsualString(cart, o2, "on");
	antiAlias = sameString(aa, "on");

	//don't fill gcPercent track by default (but fill others)
	if(sameString( tg->table, "pGC") && sameString(database,"zooHuman3"))
	{
		fillStr = cartUsualString(cart, o3, "0");
	}
	else
	{
		fillStr = cartUsualString(cart, o3, "1");
	}
	fill = atoi(fillStr);
	cartSetString(cart, o3, fillStr );

	//the 0.1 is so the label doesn't get truncated with integer valued user input min
	//display range.
	minRangeCutoff = max( atof(cartUsualString(cart,o4,"0.0"))-0.1, tg->minRange );
	maxRangeCutoff = min( atof(cartUsualString(cart,o5,"1000.0"))+0.1, tg->maxRange);

	lineGapSize = atoi(cartUsualString(cart, o6, "200"));

	//update cart settings to reflect truncated range cutoff values
	cartSetString( cart, "win", "F" );
	safef( cartStr, 64, "%g", minRangeCutoff );
	cartSetString( cart, o4, cartStr );
	safef( cartStr, 64, "%g", maxRangeCutoff );
	cartSetString( cart, o5, cartStr );

	heightPer = tg->heightPer+1;
	hFactor = (double)heightPer*tg->scaleRange;

	//errAbort( "min=%g, max=%g\n", minRangeCutoff, maxRangeCutoff );


	if( sameString( tg->table, "zoo" ) || sameString( tg->table, "zooNew" ) )
		binCount = binCount - 100;    //save some space at top, between each zoo species

	minRange = whichSampleBin( minRangeCutoff, tg->minRange, tg->maxRange, binCount );
	maxRange = whichSampleBin( maxRangeCutoff, tg->minRange, tg->maxRange, binCount );

	//errAbort( "(%g,%g) cutoff=(%g,%g)\n", tg->minRange, tg->maxRange, minRangeCutoff, maxRangeCutoff );


	if( sameString( tg->table, "zoo" ) || sameString( tg->table, "zooNew" ) )
	{
		/*Always interpolate zoo track (since gaps are explicitly defined*/
		lineGapSize = -1;
	}
	else if( tg->minRange == 0 && tg->maxRange == 8 )    //range for all L-score tracks
	{
		if( isFull )
		{
			min0 = whichSampleNum( minRange, tg->minRange, tg->maxRange, binCount );
			max0 = whichSampleNum( maxRange, tg->minRange, tg->maxRange,  binCount );
			for( i=1; i<=6; i++ )
				drawWiggleHorizontalLine(hvg, (double)i, min0, max0,
				binCount, y, hFactor, heightPer, gridColor );
		}
	}

	for(lf = tg->items; lf != NULL; lf = lf->next) 
	{
		gapPrevX = -1;
		prevX = -1;
		ybase = (int)((double)y+hFactor+(double)heightPer);


		for (sf = lf->components; sf != NULL; sf = sf->next)
		{
			sampleX = sf->start;
			sampleY = sf->end - sampleX;	// Stange encoding but so it is. 
			// It is to deal with the fact that
			// for a BED: sf->end = sf->start + length
			// but in our case length = height (or y-value)
			// so to recover height we take
			// height = sf->end - sf->start.
			// Otherwise another sf variable would 
			// be needed.


			/*mapping or sequencing gap*/
			if (sampleY == 0)
			{
				bin = -whichSampleBin( (int)((maxRange - minRange)/5.0+minRange), 
					minRange, maxRange, binCount );
				y1 = (int)((double)y+((double)bin)* hFactor+(double)heightPer);
				if( gapPrevX >= 0 )
					drawScaledBox(hvg, sampleX, gapPrevX, scale, 
					xOff, (int)y1, (int)(.10*heightPer), shadesOfGray[2]);
				gapPrevX = sampleX;
				prevX = -1; /*connect next point with gray bar too*/
				continue;
			}
			if (sampleY > maxRange)
				sampleY = maxRange;
			if (sampleY < minRange)
				sampleY = minRange;
			bin = -whichSampleBin( sampleY, minRange, maxRange, binCount );


			x1 = round((double)(sampleX-winStart)*scale) + xOff;
			y1 = (int)((double)y+((double)bin)* hFactor+(double)heightPer);



			if (prevX > 0)
			{
				y2 = prevY;
				x2 = round((double)(prevX-winStart)*scale) + xOff;
				if( wiggleType == wiggleLinearInterpolation ) 
					/*connect samples*/
				{
					if( lineGapSize < 0 || prevX - sampleX <= lineGapSize )   
						/*don't interpolate over large gaps*/
					{
						if (fill)
							hvGfxFillUnder(hvg, x1,y1, x2,y2, ybase, bColor);
						else
							hvGfxLine(hvg, x1,y1, x2,y2, color);
					}
				}
			}

			//if( x1 < 0 || x1 > tl.picWidth )
			//printf("x1 = %d, sampleX=%d, winStart = %d\n<br>", x1, sampleX, winStart );
			if( x1 >= 0 && x1 <= tl.picWidth )
			{
				/* Draw the points themselves*/
				drawScaledBox(hvg, sampleX, sampleX+1, scale, xOff, (int)y1-1, 3, color);
				if( fill )
					drawScaledBox(hvg, sampleX, sampleX+1, scale, xOff, (int)y1+2, 
					ybase-y1-2, bColor);
			}

			prevX = gapPrevX = sampleX;
			prevY = y1;
		}

		leftSide = max( tg->itemStart(tg,lf), winStart );
		rightSide = min(  tg->itemEnd(tg,lf), winEnd );

		currentX =  round((double)((int)leftSide-winStart)*scale) + xOff;
		currentXEnd =  round((double)((int)rightSide-winStart)*scale) + xOff;
		currentWidth = currentXEnd - currentX;

		if( noZoom && isFull )
		{
			fprintf(stderr, "mapBoxHc(id: %s;) in wiggleLinkedFeatures\n", 
				tg->track);
			mapBoxHc(hvg, lf->start, lf->end, currentX ,y, currentWidth,
				heightPer, tg->track, tg->mapItemName(tg, lf), tg->itemName(tg, lf));

			if( lf->next != NULL )
				y += sampleUpdateY( lf->name, lf->next->name, lineHeight );
			else
				y += lineHeight;
		}

	}
}
Beispiel #5
0
static void altGraphXDrawAt(struct track *tg, void *item, struct hvGfx *hvg, 
			    int xOff, int yOff, double scale, 
			    MgFont *font, Color color, enum trackVisibility vis)
/* Draw an altGraphX at the specified location. */
{
int i = 0;
int s =0, e=0;
int heightPer = tg->heightPer;
int start = 0, end = 0;
struct altGraphX *ag = item;
int width = 0;
int x1, x2;

/* Create a link to hgc. */
if(tg->mapsSelf && tg->mapItem)
    {
    char name[256];
    int nameWidth = 0;
    int textX = 0;
    start = max(winStart, ag->tStart);
    end = min(winEnd, ag->tEnd);
    width = (end - start) * scale;
    x1 = round((double)((int) start - winStart)*scale) + xOff;
    textX = x1;
    if(width == 0)
	width = 1;
    /* If there isn't enough room on before the left edge snap the
       label to the left edge. */
    if(withLeftLabels && tg->limitedVis == tvPack)
	{
	safef(name, sizeof(name), "%s", tg->itemName(tg, ag));
	nameWidth = mgFontStringWidth(font, name);
	textX = textX - (nameWidth + tl.nWidth/2);
	if(textX < insideX)
	    textX = insideX - nameWidth;
	width = width + (x1 - textX);
	}
    tg->mapItem(tg, hvg, ag, "notUsed", "notUsed", ag->tStart, ag->tEnd, textX, yOff, width, heightPer);
    }

/* Draw the edges (exons and introns). */
for(i= 0; i <  ag->edgeCount; i++)
    {
    Color color2;
    s = ag->vPositions[ag->edgeStarts[i]];
    e = ag->vPositions[ag->edgeEnds[i]];
    color2 = MG_BLACK;
/*  If you want to shade by number of transcripts uncomment next line. */
/* 	color2 = altGraphXColorForEdge(hvg, ag, i); */
    if(isExon(ag, i))
	{
	if(vis == tvPack)
	    drawScaledBox(hvg, s, e, scale, xOff, yOff+heightPer/2, heightPer/2, color2);
	else
	    drawScaledBox(hvg, s, e, scale, xOff, yOff, heightPer, color2);
	}
    else 
	{
	int midX;   
	s = ag->vPositions[ag->edgeStarts[i]];
	e = ag->vPositions[ag->edgeEnds[i]];
	x1 = round((double)((int) s - winStart)*scale) + xOff;
	x2 = round((double)((int) e - winStart)*scale) + xOff;
	if(vis == tvPack)
	    {
	    midX = (x1+x2)/2;
	    hvGfxLine(hvg, x1, yOff+heightPer/2, midX, yOff, color2);
	    hvGfxLine(hvg, midX, yOff, x2, yOff+heightPer/2, color2);
	    }
	else
	    hvGfxLine(hvg, x1, yOff+heightPer/2, x2, yOff+heightPer/2, color2);
	}
    }
}
Beispiel #6
0
static int rDrawTreeInLabelArea(struct hacTree *ht, struct hvGfx *hvg, enum yRetType yType, int x,
				yFromNodeFunc *yFromNode, void *yh, struct titleHelper *th,
				boolean drawRectangle)
/* Recursively draw the haplotype clustering tree in the left label area.
 * Returns pixel height for use at non-leaf levels of tree. */
{
const int branchW = 4;
int labelEnd = leftLabelX + leftLabelWidth;
if (yType == yrtStart || yType == yrtEnd)
    {
    // We're just getting vertical span of a leaf cluster, not drawing any lines.
    int yLeft, yRight;
    if (ht->left)
	yLeft = rDrawTreeInLabelArea(ht->left, hvg, yType, x, yFromNode, yh, th, drawRectangle);
    else
	yLeft = yFromNode(ht->itemOrCluster, yh, yType);
    if (ht->right)
	yRight = rDrawTreeInLabelArea(ht->right, hvg, yType, x, yFromNode, yh, th, drawRectangle);
    else
	yRight = yFromNode(ht->itemOrCluster, yh, yType);
    if (yType == yrtStart)
	return min(yLeft, yRight);
    else
	return max(yLeft, yRight);
    }
// Otherwise yType is yrtMidPoint.  If we have 2 children, we'll be drawing some lines:
if (ht->left != NULL && ht->right != NULL)
    {
    int midY;
    if (ht->childDistance == 0 || x+(2*branchW) > labelEnd)
	{
	// Treat this as a leaf cluster.
	// Recursing twice is wasteful. Could be avoided if this, and yFromNode,
	// returned both yStart and yEnd. However, the time to draw a tree of
	// 2188 hap's (1kG phase1 interim) is in the noise, so I consider it
	// not worth the effort of refactoring to save a sub-millisecond here.
	int yStartLeft = rDrawTreeInLabelArea(ht->left, hvg, yrtStart, x+branchW,
					      yFromNode, yh, th, drawRectangle);
	int yEndLeft = rDrawTreeInLabelArea(ht->left, hvg, yrtEnd, x+branchW,
					    yFromNode, yh, th, drawRectangle);
	int yStartRight = rDrawTreeInLabelArea(ht->right, hvg, yrtStart, x+branchW,
					       yFromNode, yh, th, drawRectangle);
	int yEndRight = rDrawTreeInLabelArea(ht->right, hvg, yrtEnd, x+branchW,
					     yFromNode, yh, th, drawRectangle);
	int yStart = min(yStartLeft, yStartRight);
	int yEnd = max(yEndLeft, yEndRight);
	midY = (yStart + yEnd) / 2;
	Color col = (ht->childDistance == 0) ? purple : MG_BLACK;
	if (drawRectangle || ht->childDistance != 0)
	    {
	    hvGfxLine(hvg, x+branchW, yStart, x+branchW, yEnd-1, col);
	    hvGfxLine(hvg, x+branchW, yStart, labelEnd, yStart, col);
	    hvGfxLine(hvg, x+branchW, yEnd-1, labelEnd, yEnd-1, col);
	    }
	else
	    {
	    hvGfxLine(hvg, x, midY, x+1, midY, col);
	    hvGfxLine(hvg, x+1, midY, labelEnd-1, yStart, col);
	    hvGfxLine(hvg, x+1, midY, labelEnd-1, yEnd-1, col);
	    }
	addClusterMapItem(ht, x, yStart, labelEnd, yEnd-1, th);
	}
    else
	{
	int leftMid = rDrawTreeInLabelArea(ht->left, hvg, yrtMidPoint, x+branchW,
					   yFromNode, yh, th, drawRectangle);
	int rightMid = rDrawTreeInLabelArea(ht->right, hvg, yrtMidPoint, x+branchW,
					    yFromNode, yh, th, drawRectangle);
	midY = (leftMid + rightMid) / 2;
	hvGfxLine(hvg, x+branchW, leftMid, x+branchW, rightMid, MG_BLACK);
	addClusterMapItem(ht, x, min(leftMid, rightMid), x+branchW-1, max(leftMid, rightMid), th);
	}
    if (drawRectangle || ht->childDistance != 0)
	hvGfxLine(hvg, x, midY, x+branchW, midY, MG_BLACK);
    return midY;
    }
else if (ht->left != NULL)
    return rDrawTreeInLabelArea(ht->left, hvg, yType, x, yFromNode, yh, th, drawRectangle);
else if (ht->right != NULL)
    return rDrawTreeInLabelArea(ht->right, hvg, yType, x, yFromNode, yh, th, drawRectangle);
// Leaf node -- return pixel height. Draw a line if yType is midpoint.
int y = yFromNode(ht->itemOrCluster, yh, yType);
if (yType == yrtMidPoint && x < labelEnd)
    {
    hvGfxLine(hvg, x, y, labelEnd, y, purple);
    addClusterMapItem(ht, x, y, labelEnd, y+1, th);
    }
return y;
}
Beispiel #7
0
static void drawOneRec(struct vcfRecord *rec, unsigned short *gtHapOrder, unsigned short gtHapCount,
		       struct track *tg, struct hvGfx *hvg, int xOff, int yOff, int width,
		       boolean isClustered, boolean isCenter, enum hapColorMode colorMode)
/* Draw a stack of genotype bars for this record */
{
unsigned int chromStartMap = vcfRecordTrimIndelLeftBase(rec);
unsigned int chromEndMap = vcfRecordTrimAllelesRight(rec);
const double scale = scaleForPixels(width);
int x1 = round((double)(rec->chromStart-winStart)*scale) + xOff;
int x2 = round((double)(rec->chromEnd-winStart)*scale) + xOff;
int w = x2-x1;
if (w <= 1)
    {
    x1--;
    w = 3;
    }
// When coloring mode is altOnly, we draw one extra pixel row at the top & one at bottom
// to show the locations of variants, since the reference alleles are invisible:
int extraPixel = 0;
int hapHeight = tg->height - CLIP_PAD;
if (colorMode == altOnlyMode)
    {
    hvGfxLine(hvg, x1, yOff, x2, yOff, (isClustered ? purple : shadesOfGray[5]));
    extraPixel = 1;
    hapHeight -= extraPixel*2;
    }
double hapsPerPix = (double)gtHapCount / hapHeight;
int pixIx;
for (pixIx = 0;  pixIx < hapHeight;  pixIx++)
    {
    int gtHapOrderIxStart = (int)(hapsPerPix * pixIx);
    int gtHapOrderIxEnd = round(hapsPerPix * (pixIx + 1));
    if (gtHapOrderIxEnd == gtHapOrderIxStart)
	gtHapOrderIxEnd++;
    int unks = 0, refs = 0, alts = 0;
    int gtHapOrderIx;
    for (gtHapOrderIx = gtHapOrderIxStart;  gtHapOrderIx < gtHapOrderIxEnd;  gtHapOrderIx++)
	{
	int gtHapIx = gtHapOrder[gtHapOrderIx];
	int hapIx = gtHapIx & 1;
	int gtIx = gtHapIx >>1;
	struct vcfGenotype *gt = &(rec->genotypes[gtIx]);
	if (gt->isPhased || gt->isHaploid || (gt->hapIxA == gt->hapIxB))
	    {
	    int alIx = hapIx ? gt->hapIxB : gt->hapIxA;
	    if (alIx < 0)
		unks++;
	    else if (alIx > 0)
		alts++;
	    else
		refs++;
	    }
	else
	    unks++;
	}
    int y = yOff + extraPixel + pixIx;
    Color col;
    if (colorMode == baseMode)
	col = colorByBase(refs, alts, unks, rec->alleles[0], rec->alleles[1]);
    else if (colorMode == refAltMode)
	col = colorByRefAlt(refs, alts, unks);
    else
	col = colorByAltOnly(refs, alts, unks);
    if (col != MG_WHITE)
	hvGfxLine(hvg, x1, y, x2, y, col);
    }
int yBot = yOff + tg->height - CLIP_PAD - 1;
if (isCenter)
    {
    if (colorMode == altOnlyMode)
	{
	// Colorful outline to distinguish this variant:
	hvGfxLine(hvg, x1-1, yOff, x1-1, yBot, purple);
	hvGfxLine(hvg, x2+1, yOff, x2+1, yBot, purple);
	hvGfxLine(hvg, x1-1, yOff, x2+1, yOff, purple);
	hvGfxLine(hvg, x1-1, yBot, x2+1, yBot, purple);
	}
    else
	{
	// Thick black lines to distinguish this variant:
	hvGfxBox(hvg, x1-3, yOff, 3, tg->height, MG_BLACK);
	hvGfxBox(hvg, x2, yOff, 3, tg->height, MG_BLACK);
	hvGfxLine(hvg, x1-2, yOff, x2+2, yOff, MG_BLACK);
	hvGfxLine(hvg, x1-2, yBot, x2+2, yBot, MG_BLACK);
	}
    // Mouseover was handled already by mapBoxForCenterVariant
    }
else
    {
    struct dyString *dy = dyStringNew(0);
    gtSummaryString(rec, dy);
    mapBoxHgcOrHgGene(hvg, chromStartMap, chromEndMap, x1, yOff, w, tg->height, tg->track,
		      rec->name, dy->string, NULL, TRUE, NULL);
    }
if (colorMode == altOnlyMode)
    hvGfxLine(hvg, x1, yBot, x2, yBot, (isClustered ? purple : shadesOfGray[5]));
}
Beispiel #8
0
static void longRangeDraw(struct track *tg, int seqStart, int seqEnd,
        struct hvGfx *hvg, int xOff, int yOff, int width, 
        MgFont *font, Color color, enum trackVisibility vis)
/* Draw a list of longTabix structures. */
{
double scale = scaleForWindow(width, seqStart, seqEnd);
struct bed *beds = tg->items;
unsigned int maxWidth;
struct longRange *longRange;
char buffer[1024];
char itemBuf[2048];
char statusBuf[2048];

safef(buffer, sizeof buffer, "%s.%s", tg->tdb->track, LONG_MINSCORE);
double minScore = sqlDouble(cartUsualString(cart, buffer, LONG_DEFMINSCORE));
struct longRange *longRangeList = parseLongTabix(beds, &maxWidth, minScore);

for(longRange=longRangeList; longRange; longRange=longRange->next)
    {
    safef(itemBuf, sizeof itemBuf, "%d", longRange->id);
    safef(statusBuf, sizeof statusBuf, "%g %s:%d %s:%d", longRange->score, longRange->sChrom, longRange->s, longRange->eChrom, longRange->e);

    boolean sOnScreen = (longRange->s >= seqStart) && (longRange->s < seqEnd);
    unsigned sx = 0, ex = 0;
    if (sOnScreen)
        sx = (longRange->s - seqStart) * scale + xOff;

    if (differentString(longRange->sChrom, longRange->eChrom))
        {
        if (!sOnScreen)
            continue;

        // draw the foot
        int footWidth = scale * (longRange->sw / 2);
        hvGfxLine(hvg, sx - footWidth, yOff, sx + footWidth, yOff, MG_BLUE);

        int height = tg->height/2;
        if (tg->visibility == tvDense)
            height = tg->height;
        unsigned yPos = yOff + height;
        hvGfxLine(hvg, sx, yOff, sx, yPos, MG_BLUE);
        if (tg->visibility == tvFull)
            {
            mapBoxHgcOrHgGene(hvg, longRange->s, longRange->s, sx - 2, yOff, 4, tg->height/2,
                                   tg->track, itemBuf, statusBuf, NULL, TRUE, NULL);

            safef(buffer, sizeof buffer, "%s:%d",  longRange->eChrom, longRange->e);
            hvGfxTextCentered(hvg, sx, yPos + 2, 4, 4, MG_BLUE, font, buffer);
            int width = vgGetFontStringWidth(hvg->vg, font, buffer);
            int height = vgGetFontPixelHeight(hvg->vg, font);
            mapBoxHgcOrHgGene(hvg, longRange->s, longRange->s, sx - width/2, yPos, width, height,
                                   tg->track, itemBuf, statusBuf, NULL, TRUE, NULL);
            }
        }
    else 
        {
        boolean eOnScreen = (longRange->e >= seqStart) && (longRange->e < seqEnd);
        if (!(sOnScreen || eOnScreen))
            continue;

        if (eOnScreen)
            ex = (longRange->e - seqStart) * scale + xOff;

        double longRangeWidth = longRange->e - longRange->s;
        int peak = (tg->height - 15) * ((double)longRangeWidth / maxWidth) + yOff + 10;
        if (tg->visibility == tvDense)
            peak = yOff + tg->height;
        
        if (sOnScreen)
            {
            int footWidth = scale * (longRange->sw / 2);
            hvGfxLine(hvg, sx - footWidth, yOff, sx + footWidth, yOff, color);
            hvGfxLine(hvg, sx, yOff, sx, peak, color);
            }
        if (eOnScreen)
            {
            int footWidth = scale * (longRange->ew / 2);
            hvGfxLine(hvg, ex - footWidth, yOff, ex + footWidth, yOff, color);
            hvGfxLine(hvg, ex, yOff, ex, peak, color);
            }

        if (tg->visibility == tvFull)
            {
            unsigned sPeak = sOnScreen ? sx : xOff;
            unsigned ePeak = eOnScreen ? ex : xOff + width;

            hvGfxLine(hvg, sPeak, peak, ePeak, peak, color);
            safef(statusBuf, sizeof statusBuf, "%g %s:%d %s:%d", longRange->score, longRange->sChrom, longRange->s, longRange->eChrom, longRange->e);

            if (sOnScreen)
                mapBoxHgcOrHgGene(hvg, longRange->s, longRange->e, sx - 2, yOff, 4, peak - yOff,
                                       tg->track, itemBuf, statusBuf, NULL, TRUE, NULL);
            if (eOnScreen)
                mapBoxHgcOrHgGene(hvg, longRange->s, longRange->e, ex - 2, yOff, 4, peak - yOff,
                                       tg->track, itemBuf, statusBuf, NULL, TRUE, NULL);

            mapBoxHgcOrHgGene(hvg, longRange->s, longRange->e, sPeak, peak-2, ePeak - sPeak, 4,
                                   tg->track, itemBuf, statusBuf, NULL, TRUE, NULL);

            }
        }
    }
}