src/lib/bwgQuery.c 1.21

1.21 2009/03/10 01:14:53 kent
Adding bigWigIntervalDump.
Index: src/lib/bwgQuery.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/lib/bwgQuery.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -b -B -U 4 -r1.20 -r1.21
--- src/lib/bwgQuery.c	25 Feb 2009 09:25:55 -0000	1.20
+++ src/lib/bwgQuery.c	10 Mar 2009 01:14:53 -0000	1.21
@@ -68,17 +68,19 @@
 head->itemCount = memReadBits16(&pt, isSwapped);
 *pPt = pt;
 }
 
-void bigWigBlockDump(struct bbiFile *bwf, char *chrom, FILE *out)
-/* Print out info on block starting at current position. */
+static int bigWigBlockDumpIntersectingRange(struct bbiFile *bwf, char *chrom, 
+	bits32 rangeStart, bits32 rangeEnd, int maxCount, FILE *out)
+/* Print out info on parts of block that intersect start-end, block starting at current position. */
 {
 boolean isSwapped = bwf->isSwapped;
 struct udcFile *udc = bwf->udc;
 struct bwgSectionHead head;
 bwgSectionHeadRead(bwf, &head);
 bits16 i;
 float val;
+int outCount = 0;
 
 switch (head.type)
     {
     case bwgTypeBedGraph:
@@ -88,9 +90,15 @@
 	    {
 	    bits32 start = udcReadBits32(udc, isSwapped);
 	    bits32 end = udcReadBits32(udc, isSwapped);
 	    udcMustReadOne(udc, val);
+	    if (rangeIntersection(rangeStart, rangeEnd, start, end) > 0)
+		{
 	    fprintf(out, "%s\t%u\t%u\t%g\n", chrom, start, end, val);
+		++outCount;
+		if (maxCount != 0 && outCount >= maxCount)
+		    break;
+		}
 	    }
 	break;
 	}
     case bwgTypeVariableStep:
@@ -99,27 +107,53 @@
 	for (i=0; i<head.itemCount; ++i)
 	    {
 	    bits32 start = udcReadBits32(udc, isSwapped);
 	    udcMustReadOne(udc, val);
+	    if (rangeIntersection(rangeStart, rangeEnd, start, start+head.itemSpan) > 0)
+		{
 	    fprintf(out, "%u\t%g\n", start+1, val);
+		++outCount;
+		if (maxCount != 0 && outCount >= maxCount)
+		    break;
+		}
 	    }
 	break;
 	}
     case bwgTypeFixedStep:
 	{
-	fprintf(out, "fixedStep chrom=%s start=%u step=%u span=%u\n", 
-		chrom, head.start, head.itemStep, head.itemSpan);
+	boolean gotStart = FALSE;
+	bits32 start = head.start;
 	for (i=0; i<head.itemCount; ++i)
 	    {
 	    udcMustReadOne(udc, val);
+	    if (rangeIntersection(rangeStart, rangeEnd, start, start+head.itemSpan) > 0)
+	        {
+		if (!gotStart)
+		    {
+		    fprintf(out, "fixedStep chrom=%s start=%u step=%u span=%u\n", 
+			    chrom, start, head.itemStep, head.itemSpan);
+		    gotStart = TRUE;
+		    }
 	    fprintf(out, "%g\n", val);
+		++outCount;
+		if (maxCount != 0 && outCount >= maxCount)
+		    break;
+		}
+	    start += head.itemStep;
 	    }
 	break;
 	}
     default:
         internalErr();
 	break;
     }
+return outCount;
+}
+
+void bigWigBlockDump(struct bbiFile *bwf, char *chrom, FILE *out)
+/* Print out info on block starting at current position. */
+{
+bigWigBlockDumpIntersectingRange(bwf, chrom, 0, BIGNUM, 0, out);
 }
 
 
 struct bbiInterval *bigWigIntervalQuery(struct bbiFile *bwf, char *chrom, bits32 start, bits32 end,
@@ -226,8 +260,37 @@
 slReverse(&list);
 return list;
 }
 
+int bigWigIntervalDump(struct bbiFile *bwf, char *chrom, bits32 start, bits32 end, int maxCount,
+	FILE *out)
+/* Print out info on bigWig parts that intersect chrom:start-end.   Set maxCount to 0 if you 
+ * don't care how many are printed.  Returns number printed. */
+{
+if (bwf->typeSig != bigWigSig)
+   errAbort("Trying to do bigWigIntervalDump on a non big-wig file.");
+bbiAttachUnzoomedCir(bwf);
+struct fileOffsetSize *blockList = bbiOverlappingBlocks(bwf, bwf->unzoomedCir, 
+	chrom, start, end, NULL);
+struct fileOffsetSize *block;
+struct udcFile *udc = bwf->udc;
+int printCount = 0;
+
+for (block = blockList; block != NULL; block = block->next)
+    {
+    udcSeek(udc, block->offset);
+    int oneCount = bigWigBlockDumpIntersectingRange(bwf, chrom, start, end, maxCount, out);
+    printCount += oneCount;
+    if (maxCount != 0)
+        {
+	if (oneCount >= maxCount)
+	    break;
+	maxCount -= oneCount;
+	}
+    }
+slFreeList(&blockList);
+return printCount;
+}
 
 boolean bigWigSummaryArray(char *fileName, char *chrom, bits32 start, bits32 end,
 	enum bbiSummaryType summaryType, int summarySize, double *summaryValues)
 /* Fill in summaryValues with  data from indicated chromosome range in bigWig file.