ABIF 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8209086fa0fd89bb8c512306fbb483b238265a20
4
+ data.tar.gz: e439aefb5b8f8d864365fdbd94a29ed8c6d5d422
5
+ SHA512:
6
+ metadata.gz: ca2ff2b3f0a162039a130d691093508540d1d3eb66050a5e99e35f419b1d270c2ceca5f894fa6d7e04246d42adec0aef8f84b92d635a4040e8a0ca1be849ac94
7
+ data.tar.gz: f3041d14381c0aae42617f1e2cc2a724b427392cdd65cfc33640e281f47e2515bf27e9a1e91bd99be3207c893f88d2e9f119d1e74f026e1ac9e28400e91eb963
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ABIF/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ABIF"
8
+ spec.version = ABIF::VERSION
9
+ spec.authors = ["Sascha Willuweit"]
10
+ spec.email = ["s@rprojekt.org"]
11
+ spec.description = %q{ABIF file format reader/parse/plotter.}
12
+ spec.summary = %q{Handle/Parse/Plot ABIF (Applied Biosystems Genetic Analysis Data File Format) FSA, AB1 and HID files.}
13
+ spec.homepage = "https://github.com/545ch4/ABIF"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "thor"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "minitest"
25
+ spec.add_development_dependency "rake"
26
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ABIF.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sascha Willuweit
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,34 @@
1
+ # ABIF
2
+
3
+ Handle ABIF (Applied Biosystems Genetic Analysis Data File Format) FSA, AB1 and HID files.
4
+
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'ABIF'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install ABIF
19
+
20
+
21
+ ## Usage
22
+
23
+ file = ABIF::File.new(<.fsa|ab1|hid file or IO stream>)
24
+ puts file.data.keys
25
+ puts file.data['RunN_1']
26
+
27
+
28
+ ## Contributing
29
+
30
+ 1. Fork it
31
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
32
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
33
+ 4. Push to the branch (`git push origin my-new-feature`)
34
+ 5. Create new Pull Request
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs << 'lib/ABIF'
8
+ t.test_files = FileList['test/lib/ABIF/*_test.rb']
9
+ t.verbose = true
10
+ end
11
+
12
+ task :default => :test
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require 'ABIF/CLI'
3
+ ABIF::CLI.start
@@ -0,0 +1,11 @@
1
+ require "ABIF/version"
2
+ require "ABIF/file"
3
+ # This program is a ABIF file (Applied Biosystems Genetic Analysis Data File Format)
4
+ # reader. It takes a ABIF file (.fsa) or HID file (.hid) and reading its content to several arrays of (named) datapoints.
5
+ # For in-depths description of the file format see http://www.appliedbiosystems.com/support/software_community/ABIF_File_Format.pdf
6
+ #
7
+ # Author:: Sascha Willuweit (s@rprojekt.org)
8
+ # Copyright:: Copyright (c) 2013 Sascha Willuweit
9
+ # License:: CreativeCommons Attribution-NonCommercial-ShareAlike 3.0 Unported License (see http://creativecommons.org/licenses/by-nc-sa/3.0/)
10
+ module ABIF
11
+ end
@@ -0,0 +1,91 @@
1
+ require 'thor'
2
+ require 'tempfile'
3
+ require 'open3'
4
+ require 'abif'
5
+
6
+ module ABIF
7
+ class CLI < Thor
8
+ class_option :verbose, :type => :boolean
9
+ class_option :version, :type => :boolean
10
+
11
+ desc "test FILE", "Test validity of FILE"
12
+ def test(filename)
13
+ print_version if options[:version]
14
+ puts ABIF::File.supported? filename, options.select{|option| [].include? option}
15
+ end
16
+
17
+ option :format, :type => :string, :default => 'dat'
18
+ option :normalize, :type => :string, :default => 'none'
19
+ desc "parse FILE", "parse FILE "
20
+ def parse(filename)
21
+ print_version if options[:version]
22
+
23
+ f = ABIF::File.new filename, options.select{|option| [:normalize].include? option}
24
+ refrence_datapoints = f.data['DATA_1'].size
25
+ channels = f.data.keys.select{|channel| channel.include?('DATA_') && f.data[channel].size == refrence_datapoints}
26
+ case options[:format]
27
+ when 'csv'
28
+ puts "index," << channels.join(",")
29
+ refrence_datapoints.times do |i|
30
+ puts "#{i}," << channels.map{|channel| f.data[channel][i]}.join(",")
31
+ end
32
+ when 'raw'
33
+ f.data.each do |key, d|
34
+ puts "#{key} (#{f.data_params[key].join(',')}): #{d.inspect}"
35
+ end
36
+ else
37
+ puts "index\t" << channels.join("\t")
38
+ refrence_datapoints.times do |i|
39
+ puts "#{i}\t" << channels.map{|channel| f.data[channel][i]}.join("\t")
40
+ end
41
+ end
42
+ exit 0
43
+ end
44
+
45
+ option :format, :type => :string, :default => 'png'
46
+ option :size, :type => :string, :default => '5000,6000'
47
+ option :normalize, :type => :string, :default => 'none'
48
+ desc "plot FILE OUTFILE", "plot FILE into OUTFILE"
49
+ def plot(filename, outfilename)
50
+ print_version if options[:version]
51
+
52
+ #colors = ['blue', 'green', 'black', 'red', 'orange', 'purple']
53
+
54
+ f = ABIF::File.new filename, options.select{|option| [:normalize].include? option}
55
+ tmpfile = Tempfile.new('abifcli.dat')
56
+
57
+ refrence_datapoints = f.data['DATA_1'].size
58
+ channels = f.data.keys.select{|channel| channel.include?('DATA_') && f.data[channel].size == refrence_datapoints}
59
+ tmpfile.puts "index\t" << channels.join("\t")
60
+ refrence_datapoints.times do |i|
61
+ tmpfile.puts "#{i}\t" << channels.map{|channel| f.data[channel][i]}.join("\t")
62
+ end
63
+ tmpfile.close
64
+
65
+ IO.popen(%w{gnuplot}, 'r+') do |gnuplot|
66
+ gnuplot.puts "set terminal #{options[:format].inspect} size #{options[:size]}"
67
+ gnuplot.puts "set output #{outfilename.inspect}"
68
+ gnuplot.puts "set multiplot layout #{channels.size}, 1 title #{filename.inspect}"
69
+ channels.each_with_index.map do |channel, i|
70
+ gnuplot.puts "set title #{channel.inspect}"
71
+ gnuplot.puts "unset key"
72
+ gnuplot.puts "plot #{tmpfile.path.inspect} using 1:#{i + 2} with lines lt 1 lc rgb 'grey' lw 1"
73
+ end
74
+ gnuplot.puts "unset multiplot"
75
+ gnuplot.puts "exit"
76
+ gnuplot.close_write
77
+ end
78
+
79
+ tmpfile.unlink
80
+
81
+ exit 0
82
+ end
83
+
84
+ private
85
+
86
+ def print_version
87
+ puts "abifcli version #{ABIF::VERSION}"
88
+ exit 0
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,236 @@
1
+ require 'zlib'
2
+ require 'openssl'
3
+
4
+ module ABIF
5
+ # This class holds the FSA/HID file format data. It's initialized given the filename or an IO object.
6
+ # Options are:
7
+ # [:normalize] All channels are normalized with respect to their 500-datapoint-tail assuming it means-up to 0.
8
+ class File
9
+ attr_reader :filetype, :fileversion, :data, :data_params
10
+
11
+ def self.supported?(filename_or_io, options = {})
12
+ ft = nil
13
+ fv = 0
14
+ begin
15
+ io = filename_or_io.respond_to?(:seek) ? filename_or_io : ::File.open(filename_or_io, 'rb')
16
+ (ft, fv) = io.read(6).unpack('A4S>')
17
+ rescue Exception => e
18
+ raise IOError.new "Error reding ABIF file: #{e}"
19
+ ensure
20
+ io.close unless io.nil? || !io.respond_to?(:close)
21
+ end
22
+ return ft == 'ABIF' && fv >= 100
23
+ end
24
+
25
+ def initialize(filename_or_io, options = {})
26
+ @data = {}
27
+ @data_params = {}
28
+ @named_data = {}
29
+ @some_counter = 1
30
+
31
+ @decipher = OpenSSL::Cipher.new('DES-CBC')
32
+ @decipher.key = "W\xB6\xBF\xBC\xFE\xBA1&" # [87, -74, -65, -68, -2, -70, 49, 38].pack('c*')
33
+ @decipher.iv = "\x8E\x129\x9C\aroZ" # [-114, 18, 57, -100, 7, 114, 111, 90].pack('c*')
34
+
35
+ io = nil
36
+ begin
37
+ io = filename_or_io.respond_to?(:seek) ? filename_or_io : ::File.open(filename_or_io, 'rb')
38
+ (@filetype, @fileversion) = io.read(6).unpack('A4S>')
39
+ raise IOError.new('Not an ABIF file') unless @filetype == 'ABIF' && @fileversion >= 100
40
+ header_dir_entry = unpack_dir_entry(io)
41
+ io.seek(header_dir_entry[:data_offset])
42
+ header_dir_entry[:num_elements].times do
43
+ dir_entry = unpack_dir_entry(io)
44
+ old_pos = io.pos
45
+ if dir_entry[:element_size] * dir_entry[:num_elements] > 4
46
+ io.seek(dir_entry[:data_offset])
47
+ else
48
+ io.seek(-8, IO::SEEK_CUR)
49
+ end
50
+
51
+ @data_params["#{dir_entry[:name]}_#{dir_entry[:number]}"] = [dir_entry[:element_type], dir_entry[:element_size], dir_entry[:num_elements], dir_entry[:data_size]]
52
+ @data["#{dir_entry[:name]}_#{dir_entry[:number]}"] = unpack_data(dir_entry[:element_type], dir_entry[:element_size], dir_entry[:num_elements], dir_entry[:data_size], io)
53
+ io.seek(old_pos)
54
+ end
55
+ rescue Exception => e
56
+ raise IOError.new "Error reding ABIF file: #{e}"
57
+ ensure
58
+ io.close unless io.nil? || !io.respond_to?(:close)
59
+ end
60
+
61
+ if options[:normalize] && options[:normalize] != 'none'
62
+ data_length = @data['DATA_1'].size
63
+ @data.keys.select{|key| key.include?('DATA_') && @data[key].size == data_length}.each do |key|
64
+ mean = 0.0
65
+ if options[:normalize] == 'head'
66
+ mean = @data[key][500..(500+[499,data_length].min)].inject(0.0){|t, datapoint| t + datapoint} / [499,data_length].min.to_f
67
+ elsif options[:normalize] == 'tail'
68
+ mean = @data[key][-500..-1].inject(0.0){|t, datapoint| t + datapoint} / 500.0
69
+ end
70
+ @data[key] = @data[key].map{|i| i - mean}
71
+ end
72
+ end
73
+ end
74
+
75
+ private
76
+
77
+ def some_counter
78
+ @some_counter = @some_counter + 1
79
+ end
80
+
81
+ def unpack_dir_entry(io)
82
+ dir_entry = {}
83
+ dir_entry[:name], dir_entry[:number], dir_entry[:element_type], dir_entry[:element_size], dir_entry[:num_elements], dir_entry[:data_size], dir_entry[:data_offset], dir_entry[:data_handle] = io.read(28).unpack('A4L>S>S>L>L>L>L>')
84
+ dir_entry
85
+ end
86
+
87
+ def unpack_data(type, size, num, data_size, io)
88
+ # TODO Checksum
89
+ # Fields: CkSm, CkSm-1, CkSm-2, CLst
90
+ # split by ':'
91
+ # Objects: java.util.Collections.synchronizedSortedSet/java.util.SortedSet/TreeSet/java.util.SortedSet
92
+ # MD5 BASE64Encoder "ABIFAdmin", "IdeABu++inghedsmiteCLI4S3", "81tingpH!sh1es", "eleMENT5ConsOLI45Dated", "AloysiusANdauGUST1NE"
93
+ data = io.read(data_size)
94
+ case type
95
+ when 0 # IllegalType -1-byte(s) wide
96
+ "illegal type 'IllegalType'(#{type})"
97
+ when 1 # Byte 1-byte(s) wide
98
+ data.unpack('C' * num)
99
+ when 2 # Char 1-byte(s) wide
100
+ data.unpack('C' * num)
101
+ when 3 # Word 2-byte(s) wide
102
+ data.unpack('S>' * num)
103
+ when 4 # Short 2-byte(s) wide
104
+ data.unpack('s>' * num)
105
+ when 5 # Long 4-byte(s) wide
106
+ data.unpack('l>' * num)
107
+ when 6 # Rational 8-byte(s) wide
108
+ struct = {}
109
+ struct[:numerator], struct[:denumerator] = data.unpack('l>l>' * num)
110
+ struct
111
+ when 7 # Float 4-byte(s) wide
112
+ data.unpack('g' * num)
113
+ when 8 # Double 8-byte(s) wide
114
+ data.unpack('G' * num)
115
+ when 9 # BCD 0-byte(s) wide
116
+ "unsupported type 'BCD'(#{type})"
117
+ when 10 # Date 4-byte(s) wide
118
+ struct = {}
119
+ struct[:year], struct[:month], struct[:day] = data.unpack('s>CC' * num)
120
+ struct
121
+ when 11 # Time 4-byte(s) wide
122
+ struct = {}
123
+ struct[:hour], struct[:minute], struct[:second], struct[:hsecond] = data.unpack('CCCC' * num)
124
+ struct
125
+ when 12 # Thumb 10-byte(s) wide
126
+ struct = {}
127
+ struct[:d], struct[:u], struct[:c], struct[:n] = data.unpack('l>l>CC' * num)
128
+ struct
129
+ when 13 # Boolean 1-byte(s) wide
130
+ data.unpack('C' * num).map{|x| x == 0 ? false : true}
131
+ when 14 # Point 4-byte(s) wide
132
+ struct = {}
133
+ struct[:v], struct[:h] = data.unpack('s>s>' * num)
134
+ struct
135
+ when 15 # Rect 8-byte(s) wide
136
+ struct = {}
137
+ struct[:top], struct[:left], struct[:bottom], struct[:right] = data.unpack('s>s>s>s>' * num)
138
+ struct
139
+ when 16 # VPoint 8-byte(s) wide
140
+ struct = {}
141
+ struct[:v], struct[:h] = data.unpack('l>l>' * num)
142
+ struct
143
+ when 17 # VRect 16-byte(s) wide
144
+ struct = {}
145
+ struct[:top], struct[:left], struct[:bottom], struct[:right] = data.unpack('l>l>l>l>' * num)
146
+ struct
147
+ when 18 # PString 1-byte(s) wide
148
+ data[1..data[0].unpack("C").first]
149
+ when 19 # CString 1-byte(s) wide
150
+ data[0..-2]
151
+ when 20 # Tag 8-byte(s) wide
152
+ struct = {}
153
+ struct[:name], struct[:number] = data.unpack('l>l>' * num)
154
+ struct
155
+ when 21 # DeltaLZWcompression 1-byte(s) wide
156
+ # TODO: What is a "DeltaLZWcompression" compression? Implement it the right way.
157
+ "unsupported compression 'DeltaLZWcompression'(#{type})"
158
+ when 22 # LZWcompression 1-byte(s) wide
159
+ unlzw(data.unpack('C' * size * num))
160
+ when 23 # Directory 28-byte(s) wide
161
+ unpack_dir_entry(data)
162
+ when 24 # UserType 1-byte(s) wide
163
+ "user type 'UserType'(#{type}) => #{num} elements of #{size}-byte wide struct: " << data.unpack('C' * size * num).join(', ')
164
+ when 25 # CustomUserType 1-byte(s) wide
165
+ "user type 'CustomUserType'(#{type}) => #{num} elements of #{size}-byte wide struct: " << data.unpack('C' * size * num).join(', ')
166
+ when 26 # IString 1-byte(s) wide
167
+ # TODO: What is an "IString"? Implement it the right way.
168
+ data
169
+ when 27 # compressedByte 1-byte(s) wide
170
+ decrypt(data).unpack('C' * data_size)
171
+ when 28 # compressedShort 1-byte(s) wide
172
+ decrypt(data).unpack('C' * (data_size / 2))
173
+ when 29 # compressedIString 1-byte(s) wide
174
+ # TODO: What is an "IString"? Implement it the right way.
175
+ decrypt(data)
176
+ when 30 # compressedChar 1-byte(s) wide
177
+ decrypt(data).unpack('C' * data_size)
178
+ when 31 # compressedLong 1-byte(s) wide
179
+ decrypt(data).unpack('l>' * (data_size / 4))
180
+ when 32 # compressedDouble 1-byte(s) wide
181
+ decrypt(data).unpack('G' * (data_size / 8))
182
+ when 33 # compressedCString 1-byte(s) wide
183
+ decrypt(data)[0..-2]
184
+ when 34 # compressedPString 1-byte(s) wide
185
+ decrypted = decrypt(data)
186
+ decrypted[1..decrypted[0].unpack("C").first]
187
+ when 35 # compressedFloat 1-byte(s) wide
188
+ decrypt(data).unpack('g' * (data_size / 4))
189
+ when 128 # deltaComp
190
+ # TODO: What is a "deltaComp" compression? Implement it the right way.
191
+ "unsupported compression 'deltaComp' data type '#{type}'"
192
+ when 256 # LZWComp
193
+ unlzw(data.unpack('C' * size * num))
194
+ when 384 # deltaLZW
195
+ # TODO: What is a "deltaLZW" compression? Implement it the right way.
196
+ "unsupported compression 'deltaLZW'(#{type})"
197
+ when 1024 # user
198
+ "user type 'user'(#{type}) => #{num} elements of #{size}-byte wide struct: " << data.unpack('C' * size * num).join(', ')
199
+ else
200
+ "unsupported type '#{type}': " << data.unpack('C' * size * num).join(', ')
201
+ end
202
+ end
203
+
204
+ def inflate(compressed)
205
+ Zlib::Inflate.inflate compressed
206
+ end
207
+
208
+ def unlzw(compressed)
209
+ dict_size = 256
210
+ dictionary = Hash[ Array.new(dict_size) {|i| [i.chr, i.chr]} ]
211
+
212
+ w = result = compressed.shift
213
+ for k in compressed
214
+ if dictionary.has_key?(k)
215
+ entry = dictionary[k]
216
+ elsif k == dict_size
217
+ entry = w + w[0,1]
218
+ else
219
+ raise 'Bad compressed k: %s' % k
220
+ end
221
+ result += entry
222
+
223
+ dictionary[dict_size] = w + entry[0,1]
224
+ dict_size += 1
225
+
226
+ w = entry
227
+ end
228
+ result
229
+ end
230
+
231
+ def decrypt(encrypted)
232
+ @decipher.reset
233
+ @decipher.update(encrypted) + @decipher.final
234
+ end
235
+ end
236
+ end
@@ -0,0 +1,3 @@
1
+ module ABIF
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,44 @@
1
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
2
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
3
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
4
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
5
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
6
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
7
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
8
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
9
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
10
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
11
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
12
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
13
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
14
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
15
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
16
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
17
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
18
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
19
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
20
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
21
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
22
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
23
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
24
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
25
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
26
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
27
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
28
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
29
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
30
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
31
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
32
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
33
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
34
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
35
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
36
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
37
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
38
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
39
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
40
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
41
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
42
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
43
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
44
+ NOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILENOTAVALIDABIFFILE
Binary file
@@ -0,0 +1,189 @@
1
+ require_relative '../../test_helper'
2
+
3
+ describe ABIF::File do
4
+ describe 'omitting file/filename' do
5
+ it 'raises an Error' do
6
+ Proc.new { ABIF::File.new }.must_raise ArgumentError
7
+ end
8
+ end
9
+
10
+ describe 'invalid file/filehandle' do
11
+ it 'invalid file raises an Exception' do
12
+ Proc.new { ABIF::File.new('test/files/invalid.abif') }.must_raise IOError
13
+ end
14
+
15
+ it 'non-existing file raises an Exception' do
16
+ Proc.new { ABIF::File.new('test/files/foo.abif') }.must_raise IOError
17
+ end
18
+
19
+ it 'empty filehandle raises an Exception' do
20
+ Proc.new { ABIF::File.new(File.new) }.must_raise ArgumentError
21
+ end
22
+ end
23
+
24
+ describe ABIF::File, 'valid filename' do
25
+ subject { ABIF::File.new('test/files/valid.abif') }
26
+
27
+ it 'is an instance of ABIF::File' do
28
+ subject.must_be_instance_of ABIF::File
29
+ end
30
+
31
+ it 'filetype is ABIF' do
32
+ subject.filetype.must_equal 'ABIF'
33
+ end
34
+
35
+ it 'fileversion is 101' do
36
+ subject.fileversion.must_equal 101
37
+ end
38
+
39
+ it 'data is a Hash' do
40
+ subject.data.must_be_kind_of Hash
41
+ end
42
+
43
+ {
44
+ 'AEPt_1' => '329a2798ac4a2024f904a4900de7600d',
45
+ 'AEPt_2' => '329a2798ac4a2024f904a4900de7600d',
46
+ 'APFN_2' => '509a32e5f2979be945f61cddbd14622c',
47
+ 'APXV_1' => '39c6844c921cf69656adaa2a8e4aea0c',
48
+ 'APrN_1' => '509a32e5f2979be945f61cddbd14622c',
49
+ 'APrV_1' => '3cf3aef9902754f1c9178e32f5fe1ddc',
50
+ 'APrX_1' => '773e4cd95581ad061589066058e65d4f',
51
+ 'ARTN_1' => '8d5162ca104fa7e79fe80fd92bb657fb',
52
+ 'ASPF_1' => '35dba5d75538a9bbe0b4da4422759a0e',
53
+ 'ASPt_1' => '220e850bfe79cb3526b375bc6dcdd2ef',
54
+ 'ASPt_2' => '220e850bfe79cb3526b375bc6dcdd2ef',
55
+ 'AUDT_1' => '49c8922d68864bb83c04879c1589a0fb',
56
+ 'B1Pt_1' => 'af7e8bea94ff3c20159e249200b6aa18',
57
+ 'B1Pt_2' => 'af7e8bea94ff3c20159e249200b6aa18',
58
+ 'BCTS_1' => '162bb794a66800199501e1e9de7a15df',
59
+ 'BufT_1' => '83a08dbe51340d001d2e7a3f8708e8cb',
60
+ 'CCut_1' => 'b95b0b3bc23f39b3c04bc2baf211ba5b',
61
+ 'CMNT_1' => '81bba32c7b86600386d96930ec17fda4',
62
+ 'CTID_1' => '46f79adeafce95e4fdd7b6aebad1699e',
63
+ 'CTNM_1' => '46f79adeafce95e4fdd7b6aebad1699e',
64
+ 'CTOw_1' => 'c446a4c96a0fe001210b71144c2268f9',
65
+ 'CTTL_1' => '74c70c8291e9dacf1935132d58229634',
66
+ 'CpEP_1' => '35dba5d75538a9bbe0b4da4422759a0e',
67
+ 'DATA_1' => 'c29a483afbeb83172305fb0803f3f264',
68
+ 'DATA_2' => 'd9f5d923f13c66ff2385ee9cac1ba2f3',
69
+ 'DATA_3' => 'e14a88b6353558b6af927de5ec1e070a',
70
+ 'DATA_4' => '2b60b8f09786c6c182f53da105483bba',
71
+ 'DATA_5' => '6f501928683d29942b95d5dad46e2e26',
72
+ 'DATA_6' => 'f66e5d54b3606d9e060351c85a2ef733',
73
+ 'DATA_7' => '7de240b0d5c835a9242555aaaa425d7a',
74
+ 'DATA_8' => '272c59f929d32af7a1d655d175cf7a0e',
75
+ 'DATA_9' => '66200730a3dc10020304032cc257dbd1',
76
+ 'DATA_10' => '80238386cad29c86e1afc5d9a4d6622e',
77
+ 'DATA_11' => '6d20453b6705c0144f954e9751b61c51',
78
+ 'DATA_12' => '49061ea4bee661346a8d4ece6a606a3b',
79
+ 'DCHT_1' => '8d5162ca104fa7e79fe80fd92bb657fb',
80
+ 'DSam_1' => '35dba5d75538a9bbe0b4da4422759a0e',
81
+ 'DySN_1' => 'c300e27b7c225652d4130f053f807199',
82
+ 'Dye#_1' => 'e962e23c139e7252904b9221d9967442',
83
+ 'DyeN_1' => 'b654f7796f95e5ed17096a82a0b28315',
84
+ 'DyeN_2' => '207d360b49d1b72c0c35c89833757e5c',
85
+ 'DyeN_3' => 'ac4b808acb1fc85fa0060bc92f489c69',
86
+ 'DyeN_4' => '0ac0051af6ece5afeacf8e53e1dade59',
87
+ 'DyeW_1' => 'f9639b0987d2ad3a3ae945ee29c889b4',
88
+ 'DyeW_2' => '01df866ea9d6a730be6e319110ecfda0',
89
+ 'DyeW_3' => 'c0280f103f34474ab0107746f80736fd',
90
+ 'DyeW_4' => '47f2ba5a7a71c4646d8add9de01d8368',
91
+ 'EPVt_1' => 'aea034f6800b624bf4d8d9fd4553d264',
92
+ 'EVNT_1' => '10d4ece1db63d754b5ef1ba8fb635269',
93
+ 'EVNT_2' => '9a81c64cb96fc6b7327bb2613c52e89d',
94
+ 'EVNT_3' => 'fec688b3587dff8bb2c12a59cee0763e',
95
+ 'EVNT_4' => '906341f47061764eb805b0b57b3cd7cc',
96
+ 'FTab_1' => '21beecaab27020d9069dee9a570296d8',
97
+ 'FVoc_1' => '139268d7ad20b68f72faa0b1691cac14',
98
+ 'FWO__1' => '9f40a00e83bbaf678fe218b11f81d49e',
99
+ 'Feat_1' => 'f9131fe168d95c26058ae03cff8e6be0',
100
+ 'GTyp_1' => 'c7b375c0c538659369eee293b1cd8986',
101
+ 'HCFG_1' => 'dbe992717239d8f63333a14fae4232c1',
102
+ 'HCFG_2' => '9c0224cfb93aa409728cbac69fdf614b',
103
+ 'HCFG_3' => '96cd52a8c96d12ba88c6ba36c316603d',
104
+ 'HCFG_4' => 'fed17cd2cc23396408f8c2b480d71836',
105
+ 'InSc_1' => '2a30f5f3b7d1a97cb6132480b992d984',
106
+ 'InVt_1' => '423c57007341da0749aa1d8bb0da8042',
107
+ 'LANE_1' => '6615ab6435d4f1da792f1e6fa230cb29',
108
+ 'LIMS_1' => '6b3b0fa06550a54ba95f2e78dfb213b4',
109
+ 'LNTD_1' => '8a8783242b7b77de148a06a0bab42ba9',
110
+ 'LsrP_1' => '0a4f74e275e1168915d8d512ed22bf0c',
111
+ 'MCHN_1' => 'ff90c90ed28916bb58eb2f56f425b41f',
112
+ 'MODF_1' => '013f5a3ac5836a46be81dee59261f68d',
113
+ 'MODL_1' => '59afde3cd75ce96556b9d5b3ce95fef5',
114
+ 'NAVG_1' => '35dba5d75538a9bbe0b4da4422759a0e',
115
+ 'NLNE_1' => '2375ef9e856b982a6f9e5b8fb903e6d7',
116
+ 'NOIS_1' => '60afc12c44f69325eb1906a147339931',
117
+ 'PBAS_1' => '214591fbf4e0c6032961ffb3dc685aaf',
118
+ 'PBAS_2' => '214591fbf4e0c6032961ffb3dc685aaf',
119
+ 'PCON_1' => '59cf9b876ec3410633cb72058af1cf8e',
120
+ 'PCON_2' => '59cf9b876ec3410633cb72058af1cf8e',
121
+ 'PDMF_1' => '94827116b0e6fec7abd084917c8cfc33',
122
+ 'PDMF_2' => '94827116b0e6fec7abd084917c8cfc33',
123
+ 'PLOC_1' => '87f2292a0f208ed70cb915c4d6c625e7',
124
+ 'PLOC_2' => '87f2292a0f208ed70cb915c4d6c625e7',
125
+ 'PSZE_1' => '2375ef9e856b982a6f9e5b8fb903e6d7',
126
+ 'PTYP_1' => 'f75f3b63236ce233758cc898ebe835d0',
127
+ 'PXLB_1' => 'f2577a6fc29b900fe7d4c6321346be48',
128
+ 'RGNm_1' => '779dfa8b1b7a5cfd8063493b4bf2be46',
129
+ 'RGOw_1' => 'b0b576a3a438583bd475a14acf06bf8b',
130
+ 'RMXV_1' => '2f7bb230c70819aeb10b45a709bcf48f',
131
+ 'RMdN_1' => '013f5a3ac5836a46be81dee59261f68d',
132
+ 'RMdV_1' => '2f7bb230c70819aeb10b45a709bcf48f',
133
+ 'RMdX_1' => '41b6d91073540a2a199bf9f089e11a29',
134
+ 'RPrN_1' => '21d72202012057acf64ec7d3aa52ee42',
135
+ 'RPrV_1' => '2f7bb230c70819aeb10b45a709bcf48f',
136
+ 'RUND_1' => '21e7f6441ffe6ef6c36db98592ae0810',
137
+ 'RUND_2' => '21e7f6441ffe6ef6c36db98592ae0810',
138
+ 'RUND_3' => '21e7f6441ffe6ef6c36db98592ae0810',
139
+ 'RUND_4' => '21e7f6441ffe6ef6c36db98592ae0810',
140
+ 'RUNT_1' => '42a575cff8de9a296db610df9cff6f1f',
141
+ 'RUNT_2' => '8647ea4a1090319b27562610d831172e',
142
+ 'RUNT_3' => '1523ed7e16b541e809eb6acacf5f32c1',
143
+ 'RUNT_4' => '337a52990fce3bea946d4fa60d0f51aa',
144
+ 'Rate_1' => '9f1074af1ce98833fbf4775c5f3595cb',
145
+ 'RunN_1' => '2048de7707e4fdc395175ce4784dce18',
146
+ 'S/N%_1' => 'fbd3b15939b954654a38824ec1e82eb7',
147
+ 'SCAN_1' => '329a2798ac4a2024f904a4900de7600d',
148
+ 'SMED_1' => '0edefa708c51887ad9b3fbe1ea9e7e82',
149
+ 'SMLt_1' => 'aed6e480b8aad696f3bb3a2781cd55d6',
150
+ 'SMPL_1' => '172160c679614e93d5c07ef7b7a2441f',
151
+ 'SPAC_1' => '3e58eb892f1ff04c1da6acf6509f976b',
152
+ 'SPAC_2' => 'e991d1ef3f35a5da0b8b724490a6f21a',
153
+ 'SPAC_3' => '3e58eb892f1ff04c1da6acf6509f976b',
154
+ 'SVER_1' => 'a629005e3c810e8491172eebd622a57b',
155
+ 'SVER_2' => 'cbd989d62be7257144760e24edeaf516',
156
+ 'SVER_3' => '783e7db369d5e7d7d57e5c76a1dec609',
157
+ 'Scal_1' => '8796ada1698c9940b7cf9264407731b1',
158
+ 'Scan_1' => '329a2798ac4a2024f904a4900de7600d',
159
+ 'TUBE_1' => 'aafe2f8af7d2109f20d5ae4c488bf1c6',
160
+ 'Tmpr_1' => '1be08982f722684e69bdf6c5549d67ba',
161
+ 'User_1' => 'c446a4c96a0fe001210b71144c2268f9',
162
+ 'phAR_1' => '14a685bc2583777f837ed9d24798d915',
163
+ 'phCH_1' => '89a93d4bcb2615549a98b93d2e2f5c96',
164
+ 'phDY_1' => '7153f0402307a99a60929d7b5dcd886b',
165
+ 'phQL_1' => 'e6cd5c7f942fc1c21557adbc97739b8c',
166
+ 'phTR_1' => 'b95b0b3bc23f39b3c04bc2baf211ba5b',
167
+ 'phTR_2' => '14a685bc2583777f837ed9d24798d915'
168
+ }.each do |key, md5|
169
+ it "MD5 of data['#{key}'] equals '#{md5}'" do
170
+ subject.data[key].wont_be_nil
171
+ Digest::MD5.hexdigest(subject.data[key].inspect).must_equal md5
172
+ end
173
+ end
174
+ end
175
+
176
+ describe 'supported?' do
177
+ it 'return false on unsupported file' do
178
+ ABIF::File.supported?('test/files/invalid.abif').must_equal false
179
+ end
180
+
181
+ it 'return true on supported file' do
182
+ ABIF::File.supported?('test/files/valid.abif').must_equal true
183
+ end
184
+
185
+ it 'raise an exception on non-existing file' do
186
+ Proc.new { ABIF::File.supported?('test/files/foo.abif') }.must_raise IOError
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,4 @@
1
+ gem 'minitest'
2
+ require 'minitest/autorun'
3
+ require 'minitest/pride'
4
+ require File.expand_path('../../lib/ABIF.rb', __FILE__)
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ABIF
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sascha Willuweit
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: ABIF file format reader/parse/plotter.
70
+ email:
71
+ - s@rprojekt.org
72
+ executables:
73
+ - abifcli
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - ABIF.gemspec
79
+ - Gemfile
80
+ - LICENSE.txt
81
+ - README.md
82
+ - Rakefile
83
+ - bin/abifcli
84
+ - lib/ABIF.rb
85
+ - lib/ABIF/cli.rb
86
+ - lib/ABIF/file.rb
87
+ - lib/ABIF/version.rb
88
+ - test/files/invalid.abif
89
+ - test/files/valid.abif
90
+ - test/lib/ABIF/file_test.rb
91
+ - test/test_helper.rb
92
+ homepage: https://github.com/545ch4/ABIF
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.0.6
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: Handle/Parse/Plot ABIF (Applied Biosystems Genetic Analysis Data File Format)
116
+ FSA, AB1 and HID files.
117
+ test_files:
118
+ - test/files/invalid.abif
119
+ - test/files/valid.abif
120
+ - test/lib/ABIF/file_test.rb
121
+ - test/test_helper.rb