]> git.donarmstrong.com Git - biopieces.git/blobdiff - code_ruby/lib/maasha/sam.rb
added provisional write sam support
[biopieces.git] / code_ruby / lib / maasha / sam.rb
index 7f4712bf23082364139d76b7debd5c86cef98b5f..5ef7de5fbd99a134bff197070402c5fc7b2b5af8 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 2007-2011 Martin A. Hansen.
+# Copyright (C) 2007-2013 Martin A. Hansen.
 
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -63,6 +63,7 @@ class Sam < Filesys
     bp[:STRAND]   = sam[:FLAG].revcomp? ? '-' : '+'
     bp[:S_ID]     = sam[:RNAME]
     bp[:S_BEG]    = sam[:POS]
+    bp[:S_END]    = sam[:POS] + sam[:SEQ].length - 1
     bp[:MAPQ]     = sam[:MAPQ]
     bp[:CIGAR]    = sam[:CIGAR].to_s
 
@@ -79,24 +80,48 @@ class Sam < Filesys
     end
 
     if sam.has_key? :NM and sam[:NM].to_i > 0
+      bp[:NM] = sam[:NM]
+      bp[:MD] = sam[:MD]
       bp[:ALIGN] = self.align_descriptors(sam)
     end
 
     bp
   end
 
-  # Class method to convert a Biopiece record
-  # into a SAM entry.
-  def self.to_sam(bp)
-    "FISK"
+  # Class method to create a new SAM entry from a Biopiece record.
+  # FIXME
+  def self.new_bp(bp)
+    qname = bp[:Q_ID]
+    flag  = 0
+    rname = bp[:S_ID]
+    pos   = bp[:S_BEG]
+    mapq  = bp[:MAPQ]
+    cigar = bp[:CIGAR]
+    rnext = bp[:Q_ID2]  || '*'
+    pnext = bp[:S_BEG2] || 0
+    tlen  = bp[:TLEN]   || 0
+    seq   = bp[:SEQ]
+    qual  = bp[:SCORES] || '*'
+    nm    = "NM:i:#{bp[:NM]}" if bp[:NM]
+    md    = "MD:Z:#{bp[:MD]}" if bp[:MD]
+
+    flag |= FLAG_REVCOMP if bp[:STRAND] == '+'
+
+    if qname && flag && rname && pos && mapq && cigar && rnext && pnext && tlen && seq && qual
+      ary = [qname, flag, rname, pos, mapq, cigar, rnext, pnext, tlen, seq, qual]
+      ary << nm if nm
+      ary << md if md
+      
+      ary.join("\t")
+    end
   end
 
   # Create alignment descriptors according to the KISS
   # format description:
   # http://code.google.com/p/biopieces/wiki/KissFormat
   def self.align_descriptors(sam)
-    offset     = 0
-    align      = []
+    offset = 0
+    align  = []
 
     # Insertions
     sam[:CIGAR].each do |len, op|
@@ -118,13 +143,12 @@ class Sam < Filesys
       if m =~ /\d+/      # Matches
         offset += m.to_i
       elsif m[0] == '^'  # Deletions
-        1.upto(m.size - 1).each do
-          nt = sam[:SEQ].seq[offset]
-
-          align << [offset, "#{nt}>-"]
-
-          deletions += 1
-          offset    += 1
+        m.each_char do |nt|
+          unless nt == '^'
+            align << [offset, "#{nt}>-"]
+            deletions += 1
+            offset    += 1
+          end
         end
       else               # Mismatches
         m.each_char do |nt|
@@ -476,58 +500,58 @@ class Sam < Filesys
     # Method to test if template have
     # multiple fragments in sequencing.
     def multi?
-      flag & FLAG_MULTI
+      (flag & FLAG_MULTI) == 0
     end
 
     # Method to test if each fragment
     # properly aligned according to the aligner.
     def aligned?
-      flag & FLAG_ALIGNED 
+      (flag & FLAG_ALIGNED) == 0
     end
     
     # Method to test if the fragment was unmapped.
     def unmapped?
-      flag & FLAG_UNMAPPED
+      (flag & FLAG_UNMAPPED) == 0
     end
 
     # Method to test if the next fragment was unmapped.
     def next_unmapped?
-      flag & FLAG_NEXT_UNMAPPED
+      (flag & FLAG_NEXT_UNMAPPED) == 0
     end
 
     # Method to test if the fragment was reverse complemented.
     def revcomp?
-      flag & FLAG_REVCOMP
+      (flag & FLAG_REVCOMP) == 0
     end
 
     # Method to test if the next fragment was reverse complemented.
     def next_revcomp?
-      flag & FLAG_NEXT_REVCOMP
+      (flag & FLAG_NEXT_REVCOMP) == 0
     end
 
     # Method to test if the fragment was first in the template.
     def first?
-      flag & FLAG_FIRST
+      (flag & FLAG_FIRST) == 0
     end
 
     # Method to test if the fragment was last in the template.
     def last?
-      flag & FLAG_LAST
+      (flag & FLAG_LAST) == 0
     end
 
     # Method to test for secondary alignment.
     def secondary_alignment?
-      flag & FLAG_SECONDARY_ALIGNMENT
+      (flag & FLAG_SECONDARY_ALIGNMENT) == 0
     end
 
     # Method to test for quality fail.
     def quality_fail?
-      flag & FLAG_QUALITY_FAIL
+      (flag & FLAG_QUALITY_FAIL) == 0
     end
 
     # Method to test for PCR or optical duplicates.
     def duplicates?
-      flag & FLAG_DUPLICATES
+      (flag & FLAG_DUPLICATES) == 0
     end
   end
 end