mizlab 0.1.2 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: df8aef7891b1d4362295bf293deeab71c0df4b1acdb7e67d7fbc79fe01a7f047
4
- data.tar.gz: 836d63375f5b57f0dee6c8b52602870e1bec91e49a0af6caa7133c588bf8298f
3
+ metadata.gz: ee3b63815d8af26656457f4d496fc4d5b8527cd4402591d454739052f98b6950
4
+ data.tar.gz: 7aad66b65cf70b3e820ad31626ab35c3ad924f2c8944973afa03f1768a06b56c
5
5
  SHA512:
6
- metadata.gz: 5a27e47c4d641c989a5c3d0d744f77316cd898a4172bc96e3231cc1d7b1c8f9421cf521f1c61d4af81c42f8e4acb5498702ba61c19b51200f2bb9b0a9b3d4a94
7
- data.tar.gz: a62744a6682e782a68e729fecc00e31d3685768acb52a4e86243037de2a07b96de1527d6b0c91378e1c0245061815c6663c311cefdf7fdd1ba17b27cdcbcd333
6
+ metadata.gz: 9278897277093689b3b7f855d01574e6d580ec1ff3b5a5efd3e74ec9ba1981b66ad62d2fc1cf257191e4f66697d213bc368423f829c174212fe2df81deae37af
7
+ data.tar.gz: bb2a961976d7b414e06bc99d6969752e3f54e4c472cf2faa22873116ebf1b64e8ae8769160e92c1051bbba0b5e276919a20fc84b3484d919c63aadea3aaca24d
data/Gemfile CHANGED
@@ -5,10 +5,7 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in mizlab.gemspec
6
6
  gemspec
7
7
 
8
- gem "rake", "~> 13.0"
9
-
10
- gem "minitest", "~> 5.0"
11
-
12
- gem "yard", "~> 0.9"
13
-
14
- gem "bio"
8
+ # gem "rake", "~> 13.0"
9
+ # gem "minitest", "~> 5.0"
10
+ # gem "yard", "~> 0.9"
11
+ # gem "bio", "~> 2.0.0"
data/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  [![Test](https://github.com/MizLab/Mizlab-ruby/actions/workflows/minitest.yml/badge.svg)](https://github.com/MizLab/Mizlab-ruby/actions/workflows/minitest.yml)
2
2
  [![Build page](https://github.com/MizLab/Mizlab-ruby/actions/workflows/yardoc.yml/badge.svg)](https://github.com/MizLab/Mizlab-ruby/actions/workflows/yardoc.yml)
3
+ [![Gem Version](https://badge.fury.io/rb/mizlab.svg)](https://badge.fury.io/rb/mizlab)
3
4
 
4
5
  # Mizlab-ruby
5
6
 
6
- This gem is for easy handling of the processes used in our labolatory.
7
-
7
+ This gem is for easy handling of the processes used in our laboratory.
8
8
 
9
9
  ## Installation
10
10
 
@@ -14,7 +14,7 @@ Install it yourself as:
14
14
  gem install mizlab
15
15
  ```
16
16
 
17
- or add below to your application's Gemfile:
17
+ Or add below to your application's Gemfile:
18
18
 
19
19
  ```ruby
20
20
  gem 'mizlab'
@@ -38,7 +38,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
38
38
 
39
39
  ## Contributing
40
40
 
41
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/mizlab.
41
+ Bug reports and pull requests are welcome on GitHub at https://github.com/MizLab/Mizlab-ruby
42
42
 
43
43
  ## License
44
44
 
data/Rakefile CHANGED
@@ -16,4 +16,24 @@ YARD::Rake::YardocTask.new do |t|
16
16
  t.stats_options = ["--list-undoc"]
17
17
  end
18
18
 
19
+ desc "Version up"
20
+ task :versionup do
21
+ version = ""
22
+ File.open("./lib/mizlab/version.rb") do |f|
23
+ version = f.read[(/(\d+\.\d+\.\d+)/)]
24
+ end
25
+ ver, minor_ver, hotfix = version.split(".")
26
+ hotfix = hotfix.to_i + 1
27
+ new_version = "#{ver}.#{minor_ver}.#{hotfix}"
28
+ cmd = "sed -E -i 's/[0-9]+\\.[0-9]+\\.[0-9]+/#{new_version}/' ./lib/mizlab/version.rb"
29
+ puts(cmd)
30
+ system(cmd)
31
+ cmd = "git add ./lib/mizlab/version.rb && git commit -m ':rocket: Version up'"
32
+ puts(cmd)
33
+ system(cmd)
34
+ cmd = "git tag v#{new_version}"
35
+ puts(cmd)
36
+ system(cmd)
37
+ end
38
+
19
39
  task default: :test
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mizlab
4
- VERSION = "0.1.2"
4
+ VERSION = "0.1.7"
5
5
  end
data/lib/mizlab.rb CHANGED
@@ -4,28 +4,68 @@ require_relative "mizlab/version"
4
4
  require "set"
5
5
  require "bio"
6
6
  require "stringio"
7
+ require "open3"
8
+ require "rexml/document"
7
9
 
8
10
  module Mizlab
9
11
  class << self
10
- # Fetch data via genbank
11
- # @param [String] accession Accession number Like "NC_012920".
12
- # @param [Bool] is_protein wheather the accession is protein. Default to true.
13
- # @return [Bio::GenBank] GenBank object.
14
- def getobj(accession, is_protein = false)
15
- ret = is_protein ? fetch_protein(accession) : fetch_nucleotide(accession)
16
- parse(ret) do |o|
17
- return o
12
+ # Get entry as String. You can also give a block.
13
+ # @param [String/Array] accessions Accession numbers like ["NC_012920", ...].
14
+ # @return [String] Entry as string.
15
+ # @yield [String] Entry as string.
16
+ def getent(accessions, is_protein = false)
17
+ accessions = accessions.is_a?(String) ? [accessions] : accessions
18
+ accessions.each do |acc|
19
+ ret = is_protein ? fetch_protein(acc) : fetch_nucleotide(acc)
20
+ if block_given?
21
+ yield ret
22
+ else
23
+ return ret
24
+ end
25
+ sleep(0.37) # Using 0.333... seconds, sometimes hit the NCBI rate limit
18
26
  end
19
27
  end
20
28
 
21
- # Fetch multiple data via genbank
22
- # @param [Array] accessions Array of accession string.
29
+ # Fetch data via genbank. You can also give a block.
30
+ # @param [String/Array] accessions Accession numbers Like ["NC_012920", ...].
23
31
  # @param [Bool] is_protein wheather the accession is protein. Default to true.
32
+ # @return [Bio::GenBank] GenBank object.
24
33
  # @yield [Bio::GenBank] GenBank object.
25
- def getobjs(accessions, is_protein = false)
26
- ret = is_protein ? fetch_protein(accessions) : fetch_nucleotide(accessions)
27
- parse(ret) do |o|
28
- yield o
34
+ def getobj(accessions, is_protein = false)
35
+ getent(accessions, is_protein) do |entry|
36
+ parse(entry) do |o|
37
+ if block_given?
38
+ yield o
39
+ else
40
+ return o
41
+ end
42
+ end
43
+ end
44
+ end
45
+
46
+ # Save object.
47
+ # @param [String] filename Filepath from executed source.
48
+ # @param [Bio::DB] obj Object which inherits from `Bio::DB`.
49
+ # @return [nil]
50
+ def savefile(filename, obj)
51
+ if File.exists?(filename)
52
+ yes = Set.new(["N", "n", "no"])
53
+ no = Set.new(["Y", "y", "yes"])
54
+ loop do
55
+ print("#{filename} exists already. Overwrite? [y/n] ")
56
+ inputed = gets.rstrip
57
+ if yes.include?(inputed)
58
+ return
59
+ elsif no.include?(inputed)
60
+ break
61
+ end
62
+ puts("You should input 'y' or 'n'")
63
+ end
64
+ end
65
+ File.open(filename, "w") do |f|
66
+ obj.tags.each do |t|
67
+ f.puts(obj.get(t))
68
+ end
29
69
  end
30
70
  end
31
71
 
@@ -33,7 +73,7 @@ module Mizlab
33
73
  # @param [Bio::Sequence] sequence sequence
34
74
  # @param [Hash] mappings Hash formated {String => [Float...]}. All of [Float...] must be have same dimention.
35
75
  # @param [Hash] weights Weights for some base combination.
36
- # @param [Integer] Size of window when scanning sequence. If not give this, will use `mappings.keys[0].length -1`.
76
+ # @param [Integer] window_size Size of window when scanning sequence. If not give this, will use `mappings.keys[0].length -1`.
37
77
  # @return [Array] coordinates like [[dim1...], [dim2...]...].
38
78
  def calculate_coordinates(sequence, mappings,
39
79
  weights = nil, window_size = nil)
@@ -78,8 +118,8 @@ module Mizlab
78
118
  end
79
119
 
80
120
  # Compute local patterns from coordinates.
81
- # @param [Array] x_coordinates coordinates on x.
82
- # @param [Array] y_coordinates coordinates on y.
121
+ # @param [Array] x_coordinates Coordinates on x dimention.
122
+ # @param [Array] y_coordinates Coordinates on y dimention.
83
123
  # @return [Array] Local pattern histgram (unnormalized).
84
124
  def local_patterns(x_coordinates, y_coordinates)
85
125
  length = x_coordinates.length
@@ -88,18 +128,42 @@ module Mizlab
88
128
  end
89
129
 
90
130
  filled_pixs = Set.new
91
- 0.upto(length - 2) do |idx|
92
- filled_pixs += bresenham(x_coordinates[idx].truncate, y_coordinates[idx].truncate,
93
- x_coordinates[idx + 1].truncate, y_coordinates[idx + 1].truncate)
131
+ x_coordinates[...-1].zip(y_coordinates[...-1],
132
+ x_coordinates[1...],
133
+ y_coordinates[1...]) do |x_start, y_start, x_end, y_end|
134
+ bresenham(x_start.truncate, y_start.truncate,
135
+ x_end.truncate, y_end.truncate).each do |pix|
136
+ filled_pixs.add("#{pix[0]}##{pix[1]}")
137
+ # NOTE:
138
+ # In set or hash, if including array make it so slow.
139
+ # Prevend it by converting array into symbol or freezed string.
140
+ end
94
141
  end
95
142
 
96
143
  local_pattern_list = [0] * 512
97
- get_patterns(filled_pixs) do |pix|
98
- local_pattern_list[convert(pix)] += 1
144
+ get_patterns(filled_pixs) do |pattern|
145
+ local_pattern_list[pattern] += 1
99
146
  end
100
147
  return local_pattern_list
101
148
  end
102
149
 
150
+ # Fetch Taxonomy information from Taxonomy ID. can be give block too.
151
+ # @param [String/Integer] taxonid Taxonomy ID, or Array of its.
152
+ # @return [Hash] Taxonomy informations.
153
+ # @yield [Hash] Taxonomy informations.
154
+ def fetch_taxon(taxonid)
155
+ taxonid = taxonid.is_a?(Array) ? taxonid : [taxonid]
156
+ taxonid.each do |id|
157
+ obj = Bio::NCBI::REST::EFetch.taxonomy(id, "xml")
158
+ hashed = xml_to_hash(REXML::Document.new(obj).root)
159
+ if block_given?
160
+ yield hashed[:TaxaSet][:Taxon][:LineageEx][:Taxon]
161
+ else
162
+ return hashed[:TaxaSet][:Taxon][:LineageEx][:Taxon]
163
+ end
164
+ end
165
+ end
166
+
103
167
  private
104
168
 
105
169
  def fetch_protein(accession)
@@ -111,56 +175,43 @@ module Mizlab
111
175
  end
112
176
 
113
177
  # get patterns from filled pixs.
114
- # @param [Set] filleds filled pix's coordinates.
115
- # @yield [binaries] Array like [t, f, t...].
178
+ # @param [Set] filleds Filled pix's coordinates.
179
+ # @yield [Integer] Pattern that shown as binary
116
180
  def get_patterns(filleds)
117
181
  unless filleds.is_a?(Set)
118
182
  raise TypeError, "The argument must be Set"
119
183
  end
120
184
 
121
- centers = Set.new()
185
+ centers = Set.new
122
186
  filleds.each do |focused|
123
- get_centers(focused) do |center|
187
+ x, y = focused.split("#").map(&:to_i)
188
+ get_centers(x, y) do |center|
124
189
  if centers.include?(center)
125
190
  next
126
191
  end
127
192
  centers.add(center)
128
- binaries = []
193
+ binary = ""
194
+ x, y = center.split("#").map(&:to_i)
129
195
  -1.upto(1) do |dy|
130
196
  1.downto(-1) do |dx|
131
- binaries.append(filleds.include?([center[0] + dx, center[1] + dy]))
197
+ binary += filleds.include?("#{x + dx}##{y + dy}") ? "1" : "0"
132
198
  end
133
199
  end
134
- yield binaries
200
+ yield binary.to_i(2)
135
201
  end
136
202
  end
137
203
  end
138
204
 
139
205
  # get center coordinates of all window that include focused pixel
140
- # @param [Array] focused coordinate of focused pixel
141
- # @yield [Array] center coordinates of all window
142
- def get_centers(focused)
206
+ # @param [Integer] focused_x Coordinate of focused pixel on x dimention
207
+ # @param [Integer] focused_y Coordinate of focused pixel on y dimention
208
+ # @yield [String] Center coordinates of all window as string
209
+ def get_centers(focused_x, focused_y)
143
210
  -1.upto(1) do |dy|
144
211
  1.downto(-1) do |dx|
145
- yield [focused[0] + dx, focused[1] + dy]
146
- end
147
- end
148
- end
149
-
150
- # Convert binary array to interger
151
- # @param [Array] binaries Array of binaries
152
- # @return [Integer] converted integer
153
- def convert(binaries)
154
- unless binaries.all? { |v| v.is_a?(TrueClass) || v.is_a?(FalseClass) }
155
- raise TypeError, "The argument must be Boolean"
156
- end
157
- rst = 0
158
- binaries.reverse.each_with_index do |b, i|
159
- if b
160
- rst += 2 ** i
212
+ yield "#{focused_x + dx}##{focused_y + dy}"
161
213
  end
162
214
  end
163
- return rst
164
215
  end
165
216
 
166
217
  # Compute fill pixels by bresenham algorithm
@@ -168,30 +219,42 @@ module Mizlab
168
219
  # @param [Interger] y0 the start point on y.
169
220
  # @param [Interger] x1 the end point on x.
170
221
  # @param [Interger] x1 the end point on y.
171
- # @return [Array] filled pixels
222
+ # @return [Array] Filled pixels
223
+ # ref https://aidiary.hatenablog.com/entry/20050402/1251514618 (japanese)
172
224
  def bresenham(x0, y0, x1, y1)
173
225
  if ![x0, y0, x1, y1].all? { |v| v.is_a?(Integer) }
174
226
  raise TypeError, "All of arguments must be Integer"
175
227
  end
176
- dx = (x1 - x0).abs
177
- dy = (y1 - y0).abs
178
- sx = x0 < x1 ? 1 : -1
179
- sy = y0 < y1 ? 1 : -1
180
- err = dx - dy
181
- lines = []
182
- while true
183
- lines.append([x0, y0])
184
- if (x0 == x1 && y0 == y1)
185
- break
186
- end
187
- e2 = 2 * err
188
- if e2 > -dy
189
- err = err - dy
190
- x0 = x0 + sx
228
+
229
+ dx = x1 - x0
230
+ dy = y1 - y0
231
+ step_x = dx.positive? ? 1 : -1
232
+ step_y = dy.positive? ? 1 : -1
233
+ dx, dy = [dx, dy].map { |x| (x * 2).abs }
234
+
235
+ lines = [[x0, y0]]
236
+
237
+ if dx > dy
238
+ fraction = dy - dx / 2
239
+ while x0 != x1
240
+ if fraction >= 0
241
+ y0 += step_y
242
+ fraction -= dx
243
+ end
244
+ x0 += step_x
245
+ fraction += dy
246
+ lines << [x0, y0]
191
247
  end
192
- if e2 < dx
193
- err = err + dx
194
- y0 = y0 + sy
248
+ else
249
+ fraction = dx - dy / 2
250
+ while y0 != y1
251
+ if fraction >= 0
252
+ x0 += step_x
253
+ fraction -= dx
254
+ end
255
+ y0 += step_y
256
+ fraction += dx
257
+ lines << [x0, y0]
195
258
  end
196
259
  end
197
260
  return lines
@@ -205,5 +268,71 @@ module Mizlab
205
268
  yield e
206
269
  end
207
270
  end
271
+
272
+ # Convert XML to Hash.
273
+ # @param [REXML::Document] element XML object.
274
+ # @return [Hash] Hash that converted from xml.
275
+ def xml_to_hash(element)
276
+ value = (if element.has_elements?
277
+ children = {}
278
+ element.each_element do |e|
279
+ children.merge!(xml_to_hash(e)) { |k, v1, v2| v1.is_a?(Array) ? v1 << v2 : [v1, v2] }
280
+ end
281
+ children
282
+ else
283
+ element.text
284
+ end)
285
+ return { element.name.to_sym => value }
286
+ end
287
+ end
288
+
289
+ class Blast < Bio::Blast
290
+ # Execute blast+
291
+ # @param [Bio::Sequence, Bio::Sequence::NA, Bio::Sequence::AA] q Query sequence
292
+ # @param [Hash] opts commandline arguments optionaly
293
+ # @return [Bio::Blast::Report] Result for blast+
294
+ def query(q, opts = {})
295
+ # NOTE: I dont use **kwargs for compatibility
296
+ case q
297
+ when Bio::Sequence
298
+ q = q.output(:fasta)
299
+ when Bio::Sequence::NA, Bio::Sequence::AA, Bio::Sequence::Generic
300
+ q = q.to_fasta("query", 70)
301
+ else
302
+ q = q.to_s
303
+ end
304
+ stdout, _ = exec_local(q, opts)
305
+ return parse_result(stdout)
306
+ end
307
+
308
+ private
309
+
310
+ # Execute blast on local
311
+ # @param [string] query_string Query string, fasta etc
312
+ # @param [Hash] opts commandline arguments optionaly
313
+ # @return [Array] Array [stdout, stderr] as string
314
+ # TODO: compatibility with original
315
+ def exec_local(query_string, opts = {})
316
+ # NOTE: I dont use **kwargs for compatibility
317
+ cmd = []
318
+ cmd << @program if @program
319
+ cmd += ["-db", @db] if @program
320
+ cmd += ["-outfmt", "5"]
321
+ opts.each do |kv|
322
+ cmd += kv.map(&:to_s)
323
+ end
324
+ return execute_command(cmd, stdin: query_string)
325
+ end
326
+
327
+ # Execute command on shell
328
+ # @param [Array] cmd Array of command strings that splited by white space
329
+ # @param [String] stdin String of stdin
330
+ # @return [Array] String of stdout and stderr
331
+ # @raise [IOError] Command finished without status 0
332
+ def execute_command(cmd, stdin)
333
+ stdout, stderr, status = Open3.capture3(cmd.join(" "), stdin_data: stdin)
334
+ raise IOError, stderr unless status == 0
335
+ return [stdout, stderr]
336
+ end
208
337
  end
209
338
  end
data/mizlab.gemspec CHANGED
@@ -29,8 +29,14 @@ Gem::Specification.new do |spec|
29
29
  spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
30
  spec.require_paths = ["lib"]
31
31
 
32
- # Uncomment to register a new dependency of your gem
33
- # spec.add_dependency "example-gem", "~> 1.0"
32
+ # Dependency
33
+ spec.add_dependency "bio", "~> 2.0.0"
34
+ spec.add_dependency "rexml", ">= 0"
35
+
36
+ # Dependency (for development)
37
+ spec.add_development_dependency "rake", "~> 13.0"
38
+ spec.add_development_dependency "yard", "~> 0.9"
39
+ spec.add_development_dependency "minitest", "~> 5.0"
34
40
 
35
41
  # For more information and examples about making a new gem, checkout our
36
42
  # guide at: https://bundler.io/guides/creating_gem.html
metadata CHANGED
@@ -1,15 +1,85 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mizlab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Omochice
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-22 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2021-11-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bio
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rexml
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.9'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.9'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '5.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '5.0'
13
83
  description: The tools for our laboratory
14
84
  email:
15
85
  - mochice.mls.ntl@gmail.com