604d0f187addd191e1763f053a0e36aa720f05b6
kent
  Sat Apr 6 14:37:39 2013 -0700
Adding samToBed and samToOpenBed functions.
diff --git src/lib/bamFile.c src/lib/bamFile.c
index fd52631..3e149e7 100644
--- src/lib/bamFile.c
+++ src/lib/bamFile.c
@@ -505,30 +505,70 @@
 bam_header_t *bamHeader = fh->header;
 if(bamHeader == NULL)
     return NULL;
 for(i = 0; i < bamHeader->n_targets; i++)
     {
     struct bamChromInfo *info = NULL;
     AllocVar(info);
     info->name = cloneString(bamHeader->target_name[i]);
     info->size = bamHeader->target_len[i];
     slAddHead(&list, info);
     }
 slReverse(&list);
 return list;
 }
 
+void samToOpenBed(char *samIn, FILE *f)
+/* Like samToOpenBed, but the output is the already open file f. */
+{
+samfile_t *sf = samopen(samIn, "r", NULL);
+bam_header_t *bamHeader = sf->header;
+bam1_t one;
+ZeroVar(&one);
+int err;
+while ((err = samread(sf, &one)) >= 0)
+    {
+    int32_t tid = one.core.tid;
+    if (tid < 0)
+        continue;
+    char *chrom = bamHeader->target_name[tid];
+    // Approximate here... can do better if parse cigar.
+    int start = one.core.pos;
+    int size = one.core.l_qseq;
+    int end = start + size;	
+    boolean isRc = (one.core.flag & BAM_FREVERSE);
+    char strand = '+';
+    if (isRc)
+	{
+	strand = '-';
+	reverseIntRange(&start, &end, bamHeader->target_len[tid]);
+	}
+    fprintf(f, "%s\t%d\t%d\t.\t0\t%c\n", chrom, start, end, strand);
+    }
+if (err < 0 && err != -1)
+    errnoAbort("samread err %d", err);
+samclose(sf);
+}
+
+void samToBed(char *samIn, char *bedOut)
+/* samToBed - Convert SAM file to a pretty simple minded bed file.. */
+{
+FILE *f = mustOpen(bedOut, "w");
+samToOpenBed(samIn, f);
+carefulClose(&f);
+}
+
 #else
 // If we're not compiling with samtools, make stub routines so compile won't fail:
 
 boolean bamFileExists(char *bamFileName)
 /* Return TRUE if we can successfully open the bam file and its index file. */
 {
 warn(COMPILE_WITH_SAMTOOLS, "bamFileExists");
 return FALSE;
 }
 
 samfile_t *bamOpen(char *fileOrUrl, char **retBamFileName)
 /* Return an open bam file */
 {
 warn(COMPILE_WITH_SAMTOOLS, "bamOpenUdc");
 return FALSE;
@@ -627,30 +667,44 @@
 char *bamGetTagString(const bam1_t *bam, char *tag, char *buf, size_t bufSize)
 /* If bam's tags include the given 2-character tag, place the value into
  * buf (zero-terminated, trunc'd if nec) and return a pointer to buf,
  * or NULL if tag is not present. */
 {
 errAbort(COMPILE_WITH_SAMTOOLS, "bamGetTagString");
 return NULL;
 }
 
 struct bamChromInfo *bamChromList(samfile_t *fh)
 {
 errAbort(COMPILE_WITH_SAMTOOLS, "bamChromList");
 return NULL;
 }
 
+void samToBed(char *samIn, char *bedOut)
+/* samToBed - Convert SAM file to a pretty simple minded bed file.. */
+{
+errAbort(COMPILE_WITH_SAMTOOLS, "samToBed");
+return NULL;
+}
+
+void samToOpenBed(char *samIn, FILE *bedOut)
+/* samToBed - Convert SAM file to a pretty simple minded bed file.. */
+{
+errAbort(COMPILE_WITH_SAMTOOLS, "samToOpenBed");
+return NULL;
+}
+
 #endif//ndef USE_BAM
 
 static void bamChromInfoFree(struct bamChromInfo **pInfo)
 /* Free up one chromInfo */
 {
 struct bamChromInfo *info = *pInfo;
 if (info != NULL)
     {
     freeMem(info->name);
     freez(pInfo);
     }
 }
 
 void bamChromInfoFreeList(struct bamChromInfo **pList)
 /* Free a list of dynamically allocated bamChromInfo's */