bio-samtools 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/.document +5 -0
  2. data/Gemfile +16 -0
  3. data/Gemfile.lock +24 -0
  4. data/LICENSE.txt +702 -0
  5. data/README.rdoc +85 -0
  6. data/Rakefile +59 -0
  7. data/VERSION +1 -0
  8. data/bio-samtools.gemspec +105 -0
  9. data/ext/mkrf_conf.rb +65 -0
  10. data/lib/bio-samtools.rb +2 -0
  11. data/lib/bio/.DS_Store +0 -0
  12. data/lib/bio/db/sam.rb +325 -0
  13. data/lib/bio/db/sam/bam.rb +210 -0
  14. data/lib/bio/db/sam/external/COPYING +21 -0
  15. data/lib/bio/db/sam/external/VERSION +1 -0
  16. data/lib/bio/db/sam/faidx.rb +21 -0
  17. data/lib/bio/db/sam/library.rb +25 -0
  18. data/lib/bio/db/sam/sam.rb +84 -0
  19. data/test/basictest.rb +308 -0
  20. data/test/coverage.rb +26 -0
  21. data/test/coverage_plot.rb +28 -0
  22. data/test/feature.rb +0 -0
  23. data/test/helper.rb +18 -0
  24. data/test/samples/small/ids2.txt +1 -0
  25. data/test/samples/small/sorted.bam +0 -0
  26. data/test/samples/small/test +0 -0
  27. data/test/samples/small/test.bam +0 -0
  28. data/test/samples/small/test.fa +20 -0
  29. data/test/samples/small/test.fai +0 -0
  30. data/test/samples/small/test.sai +0 -0
  31. data/test/samples/small/test.tam +10 -0
  32. data/test/samples/small/test_chr.fasta +1000 -0
  33. data/test/samples/small/test_chr.fasta.amb +2 -0
  34. data/test/samples/small/test_chr.fasta.ann +3 -0
  35. data/test/samples/small/test_chr.fasta.bwt +0 -0
  36. data/test/samples/small/test_chr.fasta.fai +1 -0
  37. data/test/samples/small/test_chr.fasta.pac +0 -0
  38. data/test/samples/small/test_chr.fasta.rbwt +0 -0
  39. data/test/samples/small/test_chr.fasta.rpac +0 -0
  40. data/test/samples/small/test_chr.fasta.rsa +0 -0
  41. data/test/samples/small/test_chr.fasta.sa +0 -0
  42. data/test/samples/small/testu.bam +0 -0
  43. data/test/samples/small/testu.bam.bai +0 -0
  44. data/test/test_bio-samtools.rb +7 -0
  45. metadata +185 -0
@@ -0,0 +1,210 @@
1
+ # require 'rubygems'
2
+ # require'ffi'
3
+ # require 'bio/db/sam/faidx'
4
+ # require 'bio/db/sam/sam'
5
+ module Bio
6
+ class DB
7
+ module SAM
8
+ module Tools
9
+ extend FFI::Library
10
+
11
+ #ffi_lib "#{File.join(File.expand_path(File.dirname(__FILE__)),'external','libbam.dylib')}"
12
+ ffi_lib Bio::DB::SAM::Library.filename
13
+
14
+ BAM_FPAIRED = 1
15
+ BAM_FPROPER_PAIR = 2
16
+ BAM_FUNMAP = 4
17
+ BAM_FMUNMAP = 8
18
+ BAM_FREVERSE = 16
19
+ BAM_FMREVERSE = 32
20
+ BAM_FREAD1 = 64
21
+ BAM_FREAD2 = 128
22
+ BAM_FSECONDARY = 256
23
+ BAM_FQCFAIL = 512
24
+ BAM_FDUP = 1024
25
+ BAM_OFDEC = 0
26
+ BAM_OFHEX = 1
27
+ BAM_OFSTR = 2
28
+ BAM_DEF_MASK = (4|256|512|1024)
29
+ BAM_CIGAR_SHIFT = 4
30
+ BAM_CIGAR_MASK = ((1 << 4) -1)
31
+ BAM_CMATCH = 0
32
+ BAM_CINS = 1
33
+ BAM_CDEL = 2
34
+ BAM_CREF_SKIP = 3
35
+ BAM_CSOFT_CLIP = 4
36
+ BAM_CHARD_CLIP = 5
37
+ BAM_CPAD = 6
38
+ class Bam1CoreT < FFI::Struct
39
+ #uint32_t bin:16, qual:8, l_qname:8;
40
+ #uint32_t flag:16, n_cigar:16;
41
+ layout(
42
+ :tid, :int32_t,
43
+ :pos, :int32_t,
44
+ :bin, :uint16,
45
+ :qual, :uint8,
46
+ :l_qname, :uint8,
47
+ :flag, :uint16,
48
+ :n_cigar, :uint16,
49
+ :l_qseq, :int32_t,
50
+ :mtid, :int32_t,
51
+ :mpos, :int32_t,
52
+ :isize, :int32_t
53
+ )
54
+ end
55
+ class Bam1T < FFI::Struct
56
+ layout(
57
+ :core, Bam1CoreT,
58
+ :l_aux, :int,
59
+ :data_len, :int,
60
+ :m_data, :int,
61
+ :data, :pointer
62
+ )
63
+ def qname
64
+ #bam1_qname(b) ((char*)((b)->data))
65
+ data = self[:data]
66
+ data.read_string()
67
+ end
68
+
69
+
70
+ Bam_NT16_Rev_Table = "=ACMGRSVTWYHKDBN"
71
+ end
72
+
73
+
74
+
75
+
76
+ attach_function :sam_open, [ :string ], :pointer
77
+ attach_function :sam_close, [ :pointer ], :void
78
+ attach_function :sam_read1, [ :pointer, :pointer, :pointer ], :int
79
+ attach_function :sam_header_read2, [ :string ], :pointer
80
+ attach_function :sam_header_read, [ :pointer ], :pointer
81
+ attach_function :sam_header_parse, [ :pointer ], :int
82
+ #attach_function :sam_header_parse_rg, [ :pointer ], :int This is declared in the .h file, but is not implemented
83
+ #attach_function :bam_strmap_put, [ :pointer, :string, :string ], :int
84
+ #attach_function :bam_strmap_get, [ :pointer, :string ], :string
85
+ #attach_function :bam_strmap_dup, [ :pointer ], :pointer
86
+ #attach_function :bam_strmap_init, [ ], :pointer
87
+ #attach_function :bam_strmap_destroy, [ :pointer ], :void
88
+ attach_function :bam_header_init, [ ], :pointer
89
+ attach_function :bam_header_destroy, [ :pointer ], :void
90
+ attach_function :bam_header_read, [ :pointer ], :pointer
91
+ attach_function :bam_header_write, [ :pointer, :pointer ], :int
92
+ attach_function :bam_read1, [ :pointer, :pointer ], :int
93
+ attach_function :bam_write1_core, [ :pointer, :pointer, :int, :pointer ], :int
94
+ attach_function :bam_write1, [ :pointer, :pointer ], :int
95
+ attach_function :bam_format1, [ :pointer, :pointer ], :string
96
+ attach_function :bam_format1_core, [ :pointer, :pointer, :int ], :string
97
+ attach_function :bam_get_library, [ :pointer, :pointer ], :string
98
+ class BamPileup1T < FFI::Struct
99
+ layout(
100
+ :b, :pointer,
101
+ :qpos, :int32_t,
102
+ :indel, :int,
103
+ :level, :int,
104
+ :is_del, :uint32,
105
+ :is_head, :uint32,
106
+ :is_tail, :uint32
107
+ )
108
+ end
109
+ attach_function :bam_plbuf_set_mask, [ :pointer, :int ], :void
110
+ callback :bam_pileup_f, [ :uint32, :uint32, :int, :pointer, :pointer ], :int
111
+ attach_function :bam_plbuf_reset, [ :pointer ], :void
112
+ attach_function :bam_plbuf_init, [ :bam_pileup_f, :pointer ], :pointer
113
+ attach_function :bam_plbuf_destroy, [ :pointer ], :void
114
+ attach_function :bam_plbuf_push, [ :pointer, :pointer ], :int
115
+ attach_function :bam_pileup_file, [ :pointer, :int, :bam_pileup_f, :pointer ], :int
116
+ attach_function :bam_lplbuf_reset, [ :pointer ], :void
117
+ attach_function :bam_lplbuf_init, [ :bam_pileup_f, :pointer ], :pointer
118
+ attach_function :bam_lplbuf_destroy, [ :pointer ], :void
119
+ attach_function :bam_lplbuf_push, [ :pointer, :pointer ], :int
120
+ attach_function :bam_index_build, [ :string ], :int
121
+ attach_function :bam_index_load, [ :string ], :pointer
122
+ attach_function :bam_index_destroy, [ :pointer ], :void
123
+
124
+ #The function for fetching stuff
125
+ #typedef int ( *bam_fetch_f)(
126
+ # const bam1_t *b,
127
+ # void *data);
128
+ callback(:bam_fetch_f, [ :pointer, :pointer ], :int)
129
+ attach_function :bam_fetch, [ :pointer, :pointer, :int, :int, :int, :pointer, :bam_fetch_f ], :int
130
+ attach_function :bam_parse_region, [ :pointer, :pointer, :pointer, :pointer, :pointer ], :int
131
+
132
+ #The second parameter must be only 2 characters long
133
+ attach_function :bam_aux_get, [ :pointer, :string], :pointer
134
+ attach_function :bam_aux2i, [ :pointer ], :int32_t
135
+ attach_function :bam_aux2f, [ :pointer ], :float
136
+ attach_function :bam_aux2d, [ :pointer ], :double
137
+ attach_function :bam_aux2A, [ :pointer ], :char
138
+ attach_function :bam_aux2Z, [ :pointer ], :string
139
+ attach_function :bam_aux_del, [ :pointer, :pointer ], :int
140
+ #The second parameter must be only 2 characters long
141
+ attach_function :bam_aux_append, [ :pointer, :string, :char, :int, :pointer ], :void
142
+ #The second parameter must be only 2 characters long
143
+ attach_function :bam_aux_get_core, [ :pointer,:string ], :pointer
144
+ attach_function :bam_calend, [ :pointer, :pointer ], :uint32
145
+ attach_function :bam_cigar2qlen, [ :pointer, :pointer ], :int32_t
146
+
147
+ #FIXME: if we see that we need this function, implement it on ruby, seems like FFI is having problems with
148
+ #te static inline.
149
+ #attach_function :bam_reg2bin, [ :uint32, :uint32 ], :int
150
+ #FIXME: if we see that we need this function, implement it on ruby, seems like FFI is having problems with
151
+ #te static inline.
152
+ #attach_function :bam_copy1, [ :pointer, :pointer ], :pointer
153
+ #FIXME: if we see that we need this function, implement it on ruby, seems like FFI is having problems with
154
+ #te static inline.
155
+ #attach_function :bam_dup1, [ :pointer ], :pointer
156
+
157
+
158
+ #bam sort
159
+ # @abstract Sort an unsorted BAM file based on the chromosome order
160
+ # and the leftmost position of an alignment
161
+ #
162
+ # @param is_by_qname whether to sort by query name
163
+ # @param fn name of the file to be sorted
164
+ # @param prefix prefix of the output and the temporary files; upon
165
+ # sucessess, prefix.bam will be written.
166
+ # @param max_mem approxiate maximum memory (very inaccurate)
167
+ #
168
+ # @discussion It may create multiple temporary subalignment files
169
+ # and then merge them by calling bam_merge_core(). This function is
170
+ # NOT thread safe.
171
+ attach_function :bam_sort_core, [:int, :string, :string, :int], :void
172
+ def self.bam_sort(bam_filename, bam_output_prefix)
173
+ is_by_name = 0
174
+ max_mem = 500000000
175
+ bam_sort_core(is_by_name, bam_filename, bam_output_prefix, max_mem)
176
+ end
177
+
178
+ # @abstract Merge multiple sorted BAM.
179
+ # @param is_by_qname whether to sort by query name
180
+ # @param out output BAM file name
181
+ # @param headers name of SAM file from which to copy '@' header lines,
182
+ # or NULL to copy them from the first file to be merged
183
+ # @param n number of files to be merged
184
+ # @param fn names of files to be merged
185
+ #
186
+ # @discussion Padding information may NOT correctly maintained. This
187
+ # function is NOT thread safe.
188
+ # int bam_merge_core(int by_qname, const char *out, const char *headers, int n, char * const *fn,
189
+ # int flag, const char *reg)
190
+
191
+ # attach_function :bam_merge_core, [:int, :string, :string, :int, :pointer, :int, :string], :int
192
+ # def self.bam_merge(bam_output_file_name, bam_array_input_file_names, rg)
193
+ # is_by_qname = 0
194
+ # headers = ""
195
+ # flag = 0
196
+ # ary = bam_array_input_file_names.map do |filename|
197
+ # FFI::MemoryPointer.from_string(filename)
198
+ # end
199
+ # ary << nil
200
+ # fns=FFI::MemoryPointer.new :pointer, ary.size
201
+ # ary.each_with_index do |p_filename, idx|
202
+ # fns[idx].put_pointer(0, p_filename)
203
+ # end
204
+ #
205
+ # bam_merge_core(is_by_qname, bam_output_file_name, headers, bam_array_input_file_names.size, fns, flag, rg)
206
+ # end
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2008-2009 Genome Research Ltd.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1 @@
1
+ 0.1.16
@@ -0,0 +1,21 @@
1
+ #require 'rubygems'
2
+ #require'ffi'
3
+ #require 'bio/db/sam/bam'
4
+ module Bio
5
+ class DB
6
+ module SAM
7
+ module Tools
8
+ extend FFI::Library
9
+ #ffi_lib "#{File.join(File.expand_path(File.dirname(__FILE__)),'external','libbam.dylib')}"
10
+ ffi_lib Bio::DB::SAM::Library.filename
11
+
12
+ attach_function :fai_build, [ :string ], :int
13
+ attach_function :fai_destroy, [ :pointer ], :void
14
+ attach_function :fai_load, [ :string ], :pointer
15
+ attach_function :fai_fetch, [ :pointer, :string, :pointer ], :string
16
+ attach_function :faidx_fetch_nseq, [ :pointer ], :int
17
+ attach_function :faidx_fetch_seq, [ :pointer, :string, :int, :int, :pointer ], :string
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,25 @@
1
+ module Bio
2
+ class DB
3
+ module SAM
4
+ module Library
5
+ #IMPORTANT NOTE: Windows library is missing in this distribution
6
+
7
+ # Return the path with the file name of the library for the specific operating system
8
+ def filename
9
+ #TODO refactor this piece of code in all the files
10
+ lib_os = case RUBY_PLATFORM
11
+ when /linux/
12
+ 'so.1'
13
+ when /darwin/
14
+ '1.dylib'
15
+ when /windows/
16
+ 'dll'
17
+ end
18
+
19
+ File.join(File.expand_path(File.dirname(__FILE__)),'external',"libbam.#{lib_os}")
20
+ end #filename
21
+ module_function :filename
22
+ end #Library
23
+ end #Sam
24
+ end #DB
25
+ end #Bio
@@ -0,0 +1,84 @@
1
+ #
2
+ # sam.rb
3
+ #
4
+ #
5
+ # Created by Ricardo Ramirez on 3/25/10.
6
+ #
7
+ # require 'rubygems'
8
+ # require'ffi'
9
+ # require 'bio/db/sam/bam'
10
+ module Bio
11
+ class DB
12
+ module SAM
13
+ module Tools
14
+ extend FFI::Library
15
+
16
+ # ffi_lib "#{File.join(File.expand_path(File.dirname(__FILE__)),'external','libbam.#{lib_os}')}"
17
+ ffi_lib Bio::DB::SAM::Library.filename
18
+
19
+ # typedef struct {
20
+ # int32_t n_targets;
21
+ # char **target_name;
22
+ # uint32_t *target_len;
23
+ # void *dict, *hash, *rg2lib;
24
+ # int l_text;
25
+ # char *text;
26
+ # } bam_header_t;
27
+ class BamHeaderT < FFI::Struct
28
+ layout(
29
+ :n_targets, :int32_t,
30
+ :target_name, :pointer,
31
+ :target_len, :pointer,
32
+ :dict, :pointer,
33
+ :hash, :pointer,
34
+ :rg2lib, :pointer,
35
+ :l_text, :int,
36
+ :text, :pointer
37
+ )
38
+ def text=(str)
39
+ @text = FFI::MemoryPointer.from_string(str)
40
+ self[:text] = @text
41
+ end
42
+ def text
43
+ @text.get_string(0)
44
+ end
45
+
46
+ end
47
+
48
+ class SamfileTX < FFI::Union
49
+ layout(
50
+ :tamr, :pointer, #Text file, read.
51
+ :bam, :pointer, #bamFile,
52
+ :tamw, :pointer #Text file, write.
53
+ )
54
+ end
55
+ # typedef struct {
56
+ # int type;
57
+ # union {
58
+ # tamFile tamr;
59
+ # bamFile bam;
60
+ # FILE *tamw;
61
+ # } x;
62
+ # bam_header_t *header;
63
+ # } samfile_t;
64
+ class SamfileT < FFI::Struct
65
+ layout(
66
+ :type, :int,
67
+ :x, SamfileTX,
68
+ :header, :pointer
69
+ #:header, BamHeaderT
70
+ )
71
+ end
72
+
73
+
74
+
75
+ attach_function :samclose, [ :pointer ], :void
76
+ attach_function :samread, [ :pointer, :pointer ], :int
77
+ attach_function :samopen, [ :string, :string, :pointer ], :pointer
78
+ attach_function :samwrite, [ :pointer, :pointer ], :int
79
+ attach_function :sampileup, [ :pointer, :int, :bam_pileup_f, :pointer ], :int
80
+ attach_function :samfaipath, [ :string ], :string
81
+ end
82
+ end
83
+ end
84
+ end
data/test/basictest.rb ADDED
@@ -0,0 +1,308 @@
1
+ $: << File.expand_path(File.dirname(__FILE__) + '/../lib')
2
+ $: << File.expand_path('.')
3
+ require "test/unit"
4
+ require "bio/db/sam"
5
+ require "bio/db/sam/sam"
6
+
7
+
8
+ class TestBioDbSam < Test::Unit::TestCase
9
+
10
+ #Set up the paths
11
+ def setup
12
+ @test_folder = "test/samples/small"
13
+ @testTAMFile = @test_folder + "/test.tam"
14
+ @testBAMFile = @test_folder + "/testu.bam"
15
+ @testReference = @test_folder + "/test_chr.fasta"
16
+
17
+ end
18
+
19
+ #Removing the index files
20
+ def teardown
21
+ begin
22
+ File.delete(@testReference + ".fai")
23
+ p "deleted: " + @testReference + ".fai "
24
+ rescue
25
+ end
26
+ begin
27
+ File.delete(@testBAMFile + ".fai")
28
+ p "deleted: " + @testBAMFile + ".bai "
29
+ rescue
30
+ end
31
+ end
32
+
33
+ def default_test
34
+ puts $LOAD_PATH
35
+ assert(true, "Unit test test")
36
+ end
37
+
38
+ def test_openSAMFile
39
+ bamfile = Bio::DB::SAM::Tools.samopen(@testTAMFile,"r",nil)
40
+ Bio::DB::SAM::Tools.samclose(bamfile)
41
+ assert(true, "file open and closed")
42
+ end
43
+
44
+ def test_new_class_empty
45
+ begin
46
+ bam = Bio::DB::Sam.new({})
47
+ assert(false, "Should fail while opening without parameters")
48
+ rescue Bio::DB::SAMException => e
49
+ puts e.message
50
+ assert(true, e.message)
51
+ end
52
+ end
53
+
54
+ def test_new_class_empty_invalid_path
55
+ begin
56
+ sam = Bio::DB::Sam.new({:bam=>"INVALID"})
57
+ sam.open
58
+ sam.close
59
+ assert(false, "Should fail with an invalid path")
60
+ rescue Bio::DB::SAMException => e
61
+ puts e.message
62
+ assert(true, e.message)
63
+ end
64
+ end
65
+
66
+ def test_class_text_read_no_faidx
67
+ sam = Bio::DB::Sam.new({:tam=>@testTAMFile})
68
+ sam.open
69
+ sam.close
70
+ assert(true, "file open and closed with the class")
71
+ end
72
+
73
+ def test_class_text_read_no_close
74
+
75
+ fam = Bio::DB::Sam.new({:tam=>@testTAMFile})
76
+ fam.open
77
+ fam = nil
78
+ ObjectSpace.garbage_collect
79
+
80
+ assert(true, "file openend but not closed")
81
+ end
82
+
83
+ def test_class_binary_read_no_close
84
+
85
+ Bio::DB::Sam.new({:bam=>@testBAMFile}).open
86
+ ObjectSpace.garbage_collect
87
+ assert(true, "BINARY file openend but not closed")
88
+ end
89
+
90
+ def test_read_coverage
91
+ sam = Bio::DB::Sam.new({:bam=>@testBAMFile, :fasta=>@testReference})
92
+ sam.open
93
+ File.open( @test_folder +"/ids2.txt", "r") do |file|
94
+ puts "file opened"
95
+ file.each_line{|line|
96
+ fetching = line.split(' ')[0]
97
+ puts "fetching: " + fetching
98
+ sam.load_reference
99
+ seq = sam.fetch_reference(fetching, 0, 16000)
100
+ # puts seq
101
+ # puts seq.length
102
+ als = sam.fetch(fetching, 0, seq.length)
103
+ # p als
104
+ if als.length() > 0 then
105
+ p fetching
106
+ p als
107
+ end
108
+ }
109
+
110
+ end
111
+ sam.close
112
+ assert(true, "Finish")
113
+ end
114
+ # def test_read_TAM_as_BAM
115
+ # begin
116
+ # sam = Bio::DB::Sam.new({:bam=>@testTAMFile})
117
+ # sam.open
118
+ # sam.close
119
+ # assert(false, "Should raise an exception for reading a BAM as TAM")
120
+ # rescue Bio::DB::SAMException => e
121
+ # assert(true, "Properly handled")
122
+ # end
123
+ # end
124
+
125
+ # def test_read_BAM_as_TAM
126
+ # begin
127
+ # sam = Bio::DB::Sam.new({:tam=>@testBAMFile})
128
+ # sam.open
129
+ # sam.close
130
+ # assert(false, "Should raise an exception for reading a BAM as TAM")
131
+ # rescue Bio::DB::SAMException => e
132
+ # assert(true, "Properly handled")
133
+ # end
134
+ # end
135
+
136
+ def test_bam_load_index
137
+ sam = Bio::DB::Sam.new({:bam=>@testBAMFile})
138
+ sam.open
139
+ index = sam.load_index
140
+ sam.close
141
+ assert(true, "BAM index loaded")
142
+ # attach_function :bam_index_build, [ :string ], :int
143
+ # attach_function :bam_index_load, [ :string ], :pointer
144
+ # attach_function :bam_index_destroy, [ :pointer ], :void
145
+ end
146
+
147
+ def test_tam_load_index
148
+ begin
149
+ sam = Bio::DB::Sam.new({:tam=>@testTAMFile})
150
+ sam.open
151
+ sam.load_index
152
+ sam.close
153
+ assert(false, "TAM index loaded")
154
+ rescue Bio::DB::SAMException => e
155
+ assert(true, "Unable to load an index for a TAM file")
156
+ end
157
+ end
158
+
159
+ def test_read_segment
160
+ sam = Bio::DB::Sam.new({:bam=>@testBAMFile})
161
+ sam.open
162
+ als = sam.fetch("chr_1", 0, 500)
163
+ p als
164
+ sam.close
165
+ assert(true, "Seems it ran the query")
166
+ #node_7263 238 60 has 550+, query from 0 to 500, something shall come....
167
+ end
168
+
169
+ def test_read_invalid_reference
170
+ sam = Bio::DB::Sam.new({:bam=>@testBAMFile})
171
+ sam.open
172
+ begin
173
+ als = sam.fetch("Chr1", 0, 500)
174
+ p als
175
+ sam.close
176
+ assert(false, "Seems it ran the query")
177
+ rescue Bio::DB::SAMException => e
178
+ p e
179
+ assert(true, "Exception generated and catched")
180
+ end
181
+ end
182
+
183
+ def test_read_invalid_reference_start_coordinate
184
+ sam = Bio::DB::Sam.new({:bam=>@testBAMFile})
185
+ sam.open
186
+ begin
187
+ als = sam.fetch("chr", -1, 500)
188
+ p als
189
+ sam.close
190
+ assert(false, "Seems it ran the query")
191
+ rescue Bio::DB::SAMException => e
192
+ p e
193
+ assert(true, "Exception generated and catched")
194
+ end
195
+ end
196
+
197
+ def test_read_invalid_reference_end_coordinate
198
+ sam = Bio::DB::Sam.new({:bam=>@testBAMFile})
199
+ sam.open
200
+ begin
201
+ als = sam.fetch("chr", 0, 50000)
202
+ p als
203
+ sam.close
204
+ assert(false, "Seems it ran the query")
205
+ rescue Bio::DB::SAMException => e
206
+ p e
207
+ assert(true, "Exception generated and catched")
208
+ end
209
+ end
210
+
211
+ def test_read_invalid_reference_swaped_coordinates
212
+ sam = Bio::DB::Sam.new({:bam=>@testBAMFile})
213
+ sam.open
214
+ begin
215
+ als = sam.fetch("chr", 500, 0)
216
+ p als
217
+ sam.close
218
+ assert(false, "Seems it ran the query")
219
+ rescue Bio::DB::SAMException => e
220
+ p e
221
+ assert(true, "Exception generated and catched")
222
+ end
223
+ end
224
+
225
+ def test_fasta_load_index
226
+ sam = Bio::DB::Sam.new({:fasta=>@testReference})
227
+ sam.load_reference
228
+ seq = sam.fetch_reference("chr_1", 0, 500)
229
+ p seq
230
+ sam.close
231
+ assert(true, "The reference was loaded")
232
+ end
233
+
234
+ def test_fasta_load_index
235
+ sam = Bio::DB::Sam.new({:fasta=>@testReference})
236
+ sam.load_reference
237
+ begin
238
+ seq = sam.fetch_reference("chr1", 0, 500)
239
+ p "Error seq:"+ seq
240
+ sam.close
241
+ assert(false, "The reference was loaded")
242
+ rescue Bio::DB::SAMException => e
243
+ p e
244
+ assert(true, "The references was not loaded")
245
+ end
246
+ end
247
+
248
+ def test_load_feature
249
+
250
+ fs = Feature.find_by_bam("chr_1", 0, 500,@testBAMFile)
251
+
252
+ p fs
253
+ assert(true, "Loaded as features")
254
+ end
255
+
256
+ def test_avg_coverage
257
+ sam = Bio::DB::Sam.new({:fasta=>@testReference, :bam=>@testBAMFile })
258
+ sam.open
259
+ cov = sam.average_coverage("chr_1", 60, 30)
260
+ p "Coverage: " + cov.to_s
261
+ sam.close
262
+ assert(true, "Average coverage ran")
263
+ assert(3 == cov, "The coverage is 3")
264
+ end
265
+
266
+
267
+ def test_chromosome_coverage
268
+ sam = Bio::DB::Sam.new({:fasta=>@testReference, :bam=>@testBAMFile })
269
+ sam.open
270
+ covs = sam.chromosome_coverage("chr_1", 0, 60)
271
+ p "Coverage: "
272
+ p covs
273
+ puts "POS\tCOV"
274
+ covs.each_with_index{ |cov, i| puts "#{i}\t#{cov}" }
275
+ sam.close
276
+ assert(true, "Average coverage ran")
277
+ #assert(3 == cov, "The coverage is 3")
278
+ end
279
+
280
+ end
281
+
282
+ class Feature
283
+ attr_reader :start, :end, :strand, :sequence, :quality
284
+
285
+ def initialize(a={})
286
+ p a
287
+ @start = a[:start]
288
+ @end = a[:enf]
289
+ @strand = a[:strand]
290
+ @sequence = a[:sequence]
291
+ @quality = a[:quality]
292
+ end
293
+
294
+ def self.find_by_bam(reference,start,stop,bam_file_path)
295
+
296
+ sam = Bio::DB::Sam.new({:bam=>bam_file_path})
297
+ features = []
298
+ sam.open
299
+
300
+ fetchAlignment = Proc.new do |a|
301
+ a.query_strand ? strand = '+' : strand = '-'
302
+ features << Feature.new({:start=>a.pos,:end=>a.calend,:strand=>strand,:sequence=>a.seq,:quality=>a.qual})
303
+ end
304
+ sam.fetch_with_function(reference, start, stop, fetchAlignment)
305
+ sam.close
306
+ features
307
+ end
308
+ end