mizlab 0.1.2 → 0.1.7

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.
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