miga-base 0.7.4.0 → 0.7.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. checksums.yaml +4 -4
  2. data/lib/miga/cli.rb +10 -8
  3. data/lib/miga/cli/action.rb +2 -3
  4. data/lib/miga/cli/action/about.rb +5 -6
  5. data/lib/miga/cli/action/add.rb +18 -12
  6. data/lib/miga/cli/action/add_result.rb +2 -3
  7. data/lib/miga/cli/action/archive.rb +1 -2
  8. data/lib/miga/cli/action/classify_wf.rb +8 -6
  9. data/lib/miga/cli/action/console.rb +0 -1
  10. data/lib/miga/cli/action/daemon.rb +7 -7
  11. data/lib/miga/cli/action/date.rb +0 -1
  12. data/lib/miga/cli/action/derep_wf.rb +5 -4
  13. data/lib/miga/cli/action/doctor.rb +28 -20
  14. data/lib/miga/cli/action/doctor/base.rb +29 -6
  15. data/lib/miga/cli/action/edit.rb +1 -2
  16. data/lib/miga/cli/action/files.rb +8 -8
  17. data/lib/miga/cli/action/find.rb +5 -6
  18. data/lib/miga/cli/action/generic.rb +7 -7
  19. data/lib/miga/cli/action/get.rb +20 -17
  20. data/lib/miga/cli/action/get_db.rb +8 -2
  21. data/lib/miga/cli/action/index_wf.rb +1 -1
  22. data/lib/miga/cli/action/init.rb +34 -29
  23. data/lib/miga/cli/action/init/daemon_helper.rb +65 -43
  24. data/lib/miga/cli/action/lair.rb +7 -7
  25. data/lib/miga/cli/action/ln.rb +6 -6
  26. data/lib/miga/cli/action/ls.rb +1 -2
  27. data/lib/miga/cli/action/ncbi_get.rb +11 -3
  28. data/lib/miga/cli/action/new.rb +4 -4
  29. data/lib/miga/cli/action/next_step.rb +0 -1
  30. data/lib/miga/cli/action/preproc_wf.rb +3 -3
  31. data/lib/miga/cli/action/quality_wf.rb +1 -1
  32. data/lib/miga/cli/action/rm.rb +2 -3
  33. data/lib/miga/cli/action/run.rb +8 -8
  34. data/lib/miga/cli/action/stats.rb +3 -3
  35. data/lib/miga/cli/action/summary.rb +7 -6
  36. data/lib/miga/cli/action/tax_dist.rb +8 -4
  37. data/lib/miga/cli/action/tax_index.rb +3 -4
  38. data/lib/miga/cli/action/tax_set.rb +7 -6
  39. data/lib/miga/cli/action/tax_test.rb +6 -5
  40. data/lib/miga/cli/action/wf.rb +21 -19
  41. data/lib/miga/cli/base.rb +34 -32
  42. data/lib/miga/cli/objects_helper.rb +24 -17
  43. data/lib/miga/cli/opt_helper.rb +3 -2
  44. data/lib/miga/common.rb +2 -5
  45. data/lib/miga/common/base.rb +15 -16
  46. data/lib/miga/common/format.rb +8 -5
  47. data/lib/miga/common/hooks.rb +1 -4
  48. data/lib/miga/common/path.rb +4 -9
  49. data/lib/miga/common/with_daemon.rb +5 -2
  50. data/lib/miga/common/with_daemon_class.rb +1 -1
  51. data/lib/miga/common/with_result.rb +2 -1
  52. data/lib/miga/daemon.rb +51 -35
  53. data/lib/miga/daemon/base.rb +0 -2
  54. data/lib/miga/dataset.rb +47 -37
  55. data/lib/miga/dataset/base.rb +52 -37
  56. data/lib/miga/dataset/hooks.rb +3 -4
  57. data/lib/miga/dataset/result.rb +17 -1
  58. data/lib/miga/json.rb +5 -7
  59. data/lib/miga/lair.rb +4 -0
  60. data/lib/miga/metadata.rb +4 -3
  61. data/lib/miga/project.rb +29 -20
  62. data/lib/miga/project/base.rb +52 -37
  63. data/lib/miga/project/dataset.rb +27 -13
  64. data/lib/miga/project/hooks.rb +0 -3
  65. data/lib/miga/project/result.rb +14 -5
  66. data/lib/miga/remote_dataset.rb +85 -72
  67. data/lib/miga/remote_dataset/base.rb +11 -13
  68. data/lib/miga/remote_dataset/download.rb +33 -12
  69. data/lib/miga/result.rb +34 -25
  70. data/lib/miga/result/base.rb +0 -2
  71. data/lib/miga/result/dates.rb +1 -3
  72. data/lib/miga/result/source.rb +15 -16
  73. data/lib/miga/result/stats.rb +36 -25
  74. data/lib/miga/tax_dist.rb +6 -3
  75. data/lib/miga/tax_index.rb +17 -17
  76. data/lib/miga/taxonomy.rb +6 -1
  77. data/lib/miga/taxonomy/base.rb +19 -15
  78. data/lib/miga/version.rb +19 -16
  79. data/test/common_test.rb +3 -11
  80. data/test/daemon_helper.rb +38 -0
  81. data/test/daemon_test.rb +73 -101
  82. data/test/dataset_test.rb +58 -59
  83. data/test/format_test.rb +3 -11
  84. data/test/hook_test.rb +50 -55
  85. data/test/json_test.rb +7 -8
  86. data/test/lair_test.rb +22 -28
  87. data/test/metadata_test.rb +6 -14
  88. data/test/project_test.rb +33 -39
  89. data/test/remote_dataset_test.rb +20 -28
  90. data/test/result_stats_test.rb +17 -27
  91. data/test/result_test.rb +41 -34
  92. data/test/tax_dist_test.rb +0 -2
  93. data/test/tax_index_test.rb +4 -10
  94. data/test/taxonomy_test.rb +7 -9
  95. data/test/test_helper.rb +42 -1
  96. data/test/with_daemon_test.rb +14 -22
  97. data/utils/cleanup-databases.rb +6 -5
  98. data/utils/distance/base.rb +0 -1
  99. data/utils/distance/commands.rb +19 -12
  100. data/utils/distance/database.rb +24 -21
  101. data/utils/distance/pipeline.rb +12 -9
  102. data/utils/distance/runner.rb +14 -13
  103. data/utils/distance/temporal.rb +1 -3
  104. data/utils/distances.rb +1 -1
  105. data/utils/domain-ess-genes.rb +7 -7
  106. data/utils/index_metadata.rb +4 -2
  107. data/utils/mytaxa_scan.rb +18 -16
  108. data/utils/representatives.rb +5 -4
  109. data/utils/requirements.txt +1 -1
  110. data/utils/subclade/base.rb +0 -1
  111. data/utils/subclade/pipeline.rb +7 -6
  112. data/utils/subclade/runner.rb +9 -9
  113. data/utils/subclade/temporal.rb +0 -2
  114. data/utils/subclades-compile.rb +39 -37
  115. data/utils/subclades.rb +1 -1
  116. metadata +3 -2
@@ -1,4 +1,3 @@
1
-
2
1
  class MiGA::Result < MiGA::MiGA
3
2
  class << self
4
3
  def RESULT_DIRS
@@ -10,4 +9,3 @@ end
10
9
 
11
10
  module MiGA::Result::Base
12
11
  end
13
-
@@ -1,4 +1,3 @@
1
-
2
1
  require 'miga/result/base'
3
2
 
4
3
  ##
@@ -29,7 +28,7 @@ module MiGA::Result::Dates
29
28
  end
30
29
 
31
30
  private
32
-
31
+
33
32
  ##
34
33
  # Internal function to detect start and end dates
35
34
  def date_at(event)
@@ -42,4 +41,3 @@ module MiGA::Result::Dates
42
41
  Time.parse(date) unless date.nil?
43
42
  end
44
43
  end
45
-
@@ -1,30 +1,30 @@
1
-
2
1
  require 'miga/result/base'
3
2
 
4
3
  ##
5
4
  # Helper module including functions to access the source of results
6
5
  module MiGA::Result::Source
7
-
8
6
  ##
9
7
  # Load and return the source (parent object) of a result
10
8
  def source
11
- @source ||= if MiGA::Project.RESULT_DIRS[key]
12
- project
13
- else
14
- project.dataset(File.basename(path, '.json'))
15
- end
9
+ @source ||=
10
+ if MiGA::Project.RESULT_DIRS[key]
11
+ project
12
+ else
13
+ project.dataset(File.basename(path, '.json'))
14
+ end
16
15
  end
17
16
 
18
17
  ##
19
18
  # Detect the result key assigned to this result
20
19
  def key
21
- @key ||= if relative_dir == 'data/90.stats' && file_path(:metadata_index)
22
- :project_stats
23
- else
24
- MiGA::Result.RESULT_DIRS.find do |k, v|
25
- "data/#{v}" == relative_dir
26
- end.first
27
- end
20
+ @key ||=
21
+ if relative_dir == 'data/90.stats' && file_path(:metadata_index)
22
+ :project_stats
23
+ else
24
+ MiGA::Result.RESULT_DIRS.find do |k, v|
25
+ "data/#{v}" == relative_dir
26
+ end.first
27
+ end
28
28
  end
29
29
 
30
30
  ##
@@ -51,7 +51,6 @@ module MiGA::Result::Source
51
51
  # so the path referencing is identical to that of +self.path+ whenever they
52
52
  # need to be compared.
53
53
  def project_path
54
- path[ 0 .. path.rindex('/data/') - 1 ]
54
+ path[0..path.rindex('/data/') - 1]
55
55
  end
56
56
  end
57
-
@@ -1,11 +1,9 @@
1
-
2
1
  require 'zlib'
3
2
  require 'miga/result/base'
4
3
 
5
4
  ##
6
5
  # Helper module including stats-specific functions for results
7
6
  module MiGA::Result::Stats
8
-
9
7
  ##
10
8
  # (Re-)calculate and save the statistics for the result
11
9
  def compute_stats
@@ -23,46 +21,55 @@ module MiGA::Result::Stats
23
21
  def compute_stats_raw_reads
24
22
  stats = {}
25
23
  if self[:files][:pair1].nil?
26
- s = MiGA::MiGA.seqs_length(file_path(:single), :fastq, gc: true)
24
+ s = MiGA::MiGA.seqs_length(file_path(:single), :fastq, gc: true, x: true)
27
25
  stats = {
28
26
  reads: s[:n],
29
27
  length_average: [s[:avg], 'bp'],
30
28
  length_standard_deviation: [s[:sd], 'bp'],
31
- g_c_content: [s[:gc], '%']}
29
+ g_c_content: [s[:gc], '%'],
30
+ x_content: [s[:x], '%']
31
+ }
32
32
  else
33
- s1 = MiGA::MiGA.seqs_length(file_path(:pair1), :fastq, gc: true)
34
- s2 = MiGA::MiGA.seqs_length(file_path(:pair2), :fastq, gc: true)
33
+ s1 = MiGA::MiGA.seqs_length(file_path(:pair1), :fastq, gc: true, x: true)
34
+ s2 = MiGA::MiGA.seqs_length(file_path(:pair2), :fastq, gc: true, x: true)
35
35
  stats = {
36
36
  read_pairs: s1[:n],
37
37
  forward_length_average: [s1[:avg], 'bp'],
38
38
  forward_length_standard_deviation: [s1[:sd], 'bp'],
39
39
  forward_g_c_content: [s1[:gc], '%'],
40
+ forward_x_content: [s1[:x], '%'],
40
41
  reverse_length_average: [s2[:avg], 'bp'],
41
42
  reverse_length_standard_deviation: [s2[:sd], 'bp'],
42
- reverse_g_c_content: [s2[:gc], '%']}
43
+ reverse_g_c_content: [s2[:gc], '%'],
44
+ reverse_x_content: [s2[:x], '%']
45
+ }
43
46
  end
44
47
  stats
45
48
  end
46
49
 
47
50
  def compute_stats_trimmed_fasta
48
51
  f = self[:files][:coupled].nil? ? file_path(:single) : file_path(:coupled)
49
- s = MiGA::MiGA.seqs_length(f, :fasta, gc: true)
52
+ s = MiGA::MiGA.seqs_length(f, :fasta, gc: true, x: true)
50
53
  {
51
54
  reads: s[:n],
52
55
  length_average: [s[:avg], 'bp'],
53
56
  length_standard_deviation: [s[:sd], 'bp'],
54
- g_c_content: [s[:gc], '%']
57
+ g_c_content: [s[:gc], '%'],
58
+ x_content: [s[:x], '%']
55
59
  }
56
60
  end
57
61
 
58
62
  def compute_stats_assembly
59
- s = MiGA::MiGA.seqs_length(file_path(:largecontigs), :fasta,
60
- n50: true, gc: true)
63
+ s = MiGA::MiGA.seqs_length(
64
+ file_path(:largecontigs), :fasta, n50: true, gc: true, x: true
65
+ )
61
66
  {
62
67
  contigs: s[:n],
63
68
  n50: [s[:n50], 'bp'],
64
69
  total_length: [s[:tot], 'bp'],
65
- g_c_content: [s[:gc], '%']
70
+ longest_sequence: [s[:max], 'bp'],
71
+ g_c_content: [s[:gc], '%'],
72
+ x_content: [s[:x], '%']
66
73
  }
67
74
  end
68
75
 
@@ -70,7 +77,8 @@ module MiGA::Result::Stats
70
77
  s = MiGA::MiGA.seqs_length(file_path(:proteins), :fasta)
71
78
  stats = {
72
79
  predicted_proteins: s[:n],
73
- average_length: [s[:avg], 'aa']}
80
+ average_length: [s[:avg], 'aa']
81
+ }
74
82
  asm = source.result(:assembly)
75
83
  unless asm.nil? or asm[:stats][:total_length].nil?
76
84
  stats[:coding_density] =
@@ -92,7 +100,7 @@ module MiGA::Result::Stats
92
100
  def compute_stats_essential_genes
93
101
  stats = {}
94
102
  if source.is_multi?
95
- stats = {median_copies: 0, mean_copies: 0}
103
+ stats = { median_copies: 0, mean_copies: 0 }
96
104
  File.open(file_path(:report), 'r') do |fh|
97
105
  fh.each_line do |ln|
98
106
  if /^! (Mean|Median) number of copies per model: (.*)\./.match(ln)
@@ -103,8 +111,8 @@ module MiGA::Result::Stats
103
111
  else
104
112
  # Fix estimate by domain
105
113
  if !(tax = source.metadata[:tax]).nil? &&
106
- %w[Archaea Bacteria].include?(tax[:d]) &&
107
- file_path(:raw_report).nil?
114
+ %w[Archaea Bacteria].include?(tax[:d]) &&
115
+ file_path(:raw_report).nil?
108
116
  scr = "#{MiGA::MiGA.root_path}/utils/domain-ess-genes.rb"
109
117
  rep = file_path(:report)
110
118
  rc_p = File.expand_path('.miga_rc', ENV['HOME'])
@@ -115,7 +123,7 @@ module MiGA::Result::Stats
115
123
  add_file(:report, "#{source.name}.ess/log.domain")
116
124
  end
117
125
  # Extract/compute quality values
118
- stats = {completeness: [0.0, '%'], contamination: [0.0, '%']}
126
+ stats = { completeness: [0.0, '%'], contamination: [0.0, '%'] }
119
127
  File.open(file_path(:report), 'r') do |fh|
120
128
  fh.each_line do |ln|
121
129
  if /^! (Completeness|Contamination): (.*)%/.match(ln)
@@ -124,22 +132,24 @@ module MiGA::Result::Stats
124
132
  end
125
133
  end
126
134
  stats[:quality] = stats[:completeness][0] - stats[:contamination][0] * 5
127
- source.metadata[:quality] = case stats[:quality]
128
- when 80..100 ; :excellent
129
- when 50..80 ; :high
130
- when 20..50 ; :intermediate
131
- else ; :low
132
- end
135
+ source.metadata[:quality] =
136
+ case stats[:quality]
137
+ when 80..100; :excellent
138
+ when 50..80; :high
139
+ when 20..50; :intermediate
140
+ else; :low
141
+ end
133
142
  source.save
134
143
  end
135
144
  stats
136
145
  end
137
146
 
138
147
  def compute_stats_ssu
139
- stats = {ssu: 0, complete_ssu: 0}
148
+ stats = { ssu: 0, complete_ssu: 0 }
140
149
  Zlib::GzipReader.open(file_path(:gff)) do |fh|
141
150
  fh.each_line do |ln|
142
151
  next if ln =~ /^#/
152
+
143
153
  rl = ln.chomp.split("\t")
144
154
  len = (rl[4].to_i - rl[3].to_i).abs + 1
145
155
  stats[:max_length] = [stats[:max_length] || 0, len].max
@@ -158,8 +168,9 @@ module MiGA::Result::Stats
158
168
  stats[:aai] = [$2.to_f, '%']
159
169
  3.times { fh.gets }
160
170
  fh.each_line do |ln|
161
- row = ln.chomp.gsub(/^\s*/,'').split(/\s+/)
171
+ row = ln.chomp.gsub(/^\s*/, '').split(/\s+/)
162
172
  break if row.empty?
173
+
163
174
  stats[:"#{row[0]}_pvalue"] = row[2].to_f unless row[0] == 'root'
164
175
  end
165
176
  end
data/lib/miga/tax_dist.rb CHANGED
@@ -10,7 +10,6 @@ require 'zlib'
10
10
  module MiGA::TaxDist
11
11
  # Class-level
12
12
  class << self
13
-
14
13
  ##
15
14
  # Absolute path to the :intax or :novel data file (determined by +test+) for
16
15
  # AAI, determined for options +opts+. Supported options:
@@ -20,8 +19,10 @@ module MiGA::TaxDist
20
19
  engine = opts[:engine].to_s.downcase.to_sym
21
20
  test = test.to_s.downcase.to_sym
22
21
  return nil unless %i[intax novel].include? test
22
+
23
23
  engine = :blast if %i[blast+ blat].include? engine
24
24
  return nil unless %i[blast diamond].include? engine
25
+
25
26
  File.expand_path("../_data/aai-#{test}-#{engine}.tsv.gz", __FILE__)
26
27
  end
27
28
 
@@ -43,6 +44,7 @@ module MiGA::TaxDist
43
44
  keys.each do |i|
44
45
  v = row.shift
45
46
  next if v == 'NA' # <- missing data
47
+
46
48
  rank = i.zero? ? :root : MiGA::Taxonomy.KNOWN_RANKS[i]
47
49
  vals[rank] = v.to_f
48
50
  end
@@ -63,8 +65,8 @@ module MiGA::TaxDist
63
65
  # with cannonical rank (as in MiGA::Taxonomy) and estimated p-value.
64
66
  def aai_taxtest(aai, test, opts = {})
65
67
  meaning = {
66
- most_likely: [0.00, 0.01],
67
- probably: [0.01, 0.10],
68
+ most_likely: [0.00, 0.01],
69
+ probably: [0.01, 0.10],
68
70
  possibly_even: [0.10, 0.50]
69
71
  }
70
72
  pvalues = aai_pvalues(aai, test, opts)
@@ -73,6 +75,7 @@ module MiGA::TaxDist
73
75
  lwr, upr = thresholds
74
76
  min = pvalues.values.select { |v| v < upr }.max
75
77
  return out if min.nil?
78
+
76
79
  if min >= lwr
77
80
  v = pvalues.select { |_, vj| vj == min }
78
81
  out[phrase] = (test == :intax ? v.reverse_each : v).first
@@ -6,7 +6,6 @@ require 'miga/taxonomy'
6
6
  ##
7
7
  # Indexing methods based on taxonomy.
8
8
  class MiGA::TaxIndex < MiGA::MiGA
9
-
10
9
  # Instance-level
11
10
 
12
11
  ##
@@ -26,9 +25,11 @@ class MiGA::TaxIndex < MiGA::MiGA
26
25
  # Index +dataset+, a MiGA::Dataset object.
27
26
  def <<(dataset)
28
27
  return nil if dataset.metadata[:tax].nil?
28
+
29
29
  taxon = @root
30
30
  MiGA::Taxonomy.KNOWN_RANKS.each do |rank|
31
31
  next if rank == :ns
32
+
32
33
  taxon = taxon.add_child(rank, dataset.metadata[:tax][rank])
33
34
  end
34
35
  taxon.add_dataset dataset
@@ -43,7 +44,7 @@ class MiGA::TaxIndex < MiGA::MiGA
43
44
  select = []
44
45
  loop do
45
46
  new_taxa = []
46
- taxa.map{ |tx| tx.children }.flatten.each do |ch|
47
+ taxa.map { |tx| tx.children }.flatten.each do |ch|
47
48
  if ch.rank == rank
48
49
  select << ch
49
50
  elsif not ch.children.empty?
@@ -59,7 +60,8 @@ class MiGA::TaxIndex < MiGA::MiGA
59
60
  # Generate JSON String for the index.
60
61
  def to_json
61
62
  MiGA::Json.generate(
62
- { root: root.to_hash, datasets: datasets.map{ |d| d.name } })
63
+ { root: root.to_hash, datasets: datasets.map { |d| d.name } }
64
+ )
63
65
  end
64
66
 
65
67
  ##
@@ -72,7 +74,6 @@ end
72
74
  ##
73
75
  # Helper class for MiGA::TaxIndex.
74
76
  class MiGA::TaxIndexTaxon < MiGA::MiGA
75
-
76
77
  # Instance-level
77
78
 
78
79
  ##
@@ -96,14 +97,14 @@ class MiGA::TaxIndexTaxon < MiGA::MiGA
96
97
 
97
98
  ##
98
99
  # String representation of the taxon.
99
- def tax_str ; "#{rank}:#{name.nil? ? '?' : name}" ; end
100
+ def tax_str; "#{rank}:#{name.nil? ? '?' : name}"; end
100
101
 
101
102
  ##
102
103
  # Add child at +rank+ with +name+.
103
104
  def add_child(rank, name)
104
105
  rank = rank.to_sym
105
106
  name = name.miga_name unless name.nil?
106
- child = children.find{ |it| it.rank==rank and it.name==name }
107
+ child = children.find { |it| it.rank == rank and it.name == name }
107
108
  if child.nil?
108
109
  child = MiGA::TaxIndexTaxon.new(rank, name)
109
110
  @children << child
@@ -113,45 +114,44 @@ class MiGA::TaxIndexTaxon < MiGA::MiGA
113
114
 
114
115
  ##
115
116
  # Add dataset at the current taxon (not children).
116
- def add_dataset(dataset) @datasets << dataset ; end
117
+ def add_dataset(dataset) @datasets << dataset; end
117
118
 
118
119
  ##
119
120
  # Get the number of datasets in the taxon (including children).
120
121
  def datasets_count
121
- children.map{ |it| it.datasets_count }.reduce(datasets.size, :+)
122
+ children.map { |it| it.datasets_count }.reduce(datasets.size, :+)
122
123
  end
123
124
 
124
125
  ##
125
126
  # Get all the datasets in the taxon (including children).
126
127
  def all_datasets
127
- children.map{ |it| it.datasets }.reduce(datasets, :+)
128
+ children.map { |it| it.datasets }.reduce(datasets, :+)
128
129
  end
129
130
 
130
131
  ##
131
132
  # JSON String of the taxon.
132
133
  def to_json(*a)
133
- { str:tax_str, datasets:datasets.map{|d| d.name},
134
- children:children }.to_json(a)
134
+ { str: tax_str, datasets: datasets.map { |d| d.name },
135
+ children: children }.to_json(a)
135
136
  end
136
137
 
137
138
  ##
138
139
  # Hash representation of the taxon.
139
140
  def to_hash
140
- { str:tax_str, datasets:datasets.map{|d| d.name},
141
- children:children.map{ |it| it.to_hash } }
141
+ { str: tax_str, datasets: datasets.map { |d| d.name },
142
+ children: children.map { |it| it.to_hash } }
142
143
  end
143
144
 
144
145
  ##
145
146
  # Tabular String of the taxon.
146
- def to_tab(unknown, indent=0)
147
+ def to_tab(unknown, indent = 0)
147
148
  o = ''
148
149
  if unknown or not datasets.empty? or not name.nil?
149
150
  o = "#{' ' * indent}#{tax_str}: #{datasets_count}\n"
150
151
  end
151
152
  indent += 2
152
- datasets.each{ |ds| o << "#{' ' * indent}# #{ds.name}\n" }
153
- children.each{ |it| o << it.to_tab(unknown, indent) }
153
+ datasets.each { |ds| o << "#{' ' * indent}# #{ds.name}\n" }
154
+ children.each { |it| o << it.to_tab(unknown, indent) }
154
155
  o
155
156
  end
156
-
157
157
  end
data/lib/miga/taxonomy.rb CHANGED
@@ -45,6 +45,7 @@ class MiGA::Taxonomy < MiGA::MiGA
45
45
  when Hash
46
46
  value.each do |r, n|
47
47
  next if n.nil? || n == ''
48
+
48
49
  @ranks[self.class.normalize_rank(r)] = n.tr('_', ' ')
49
50
  end
50
51
  when Array
@@ -87,6 +88,7 @@ class MiGA::Taxonomy < MiGA::MiGA
87
88
  # the alternative (or master) is replaced instead if +replace+ is true.
88
89
  def add_alternative(tax, replace = true)
89
90
  raise 'Unsupported taxonomy class.' unless tax.is_a? MiGA::Taxonomy
91
+
90
92
  alt_ns = alternative(tax.namespace)
91
93
  if !replace || tax.namespace.nil? || alt_ns.nil?
92
94
  @alt << tax
@@ -96,7 +98,7 @@ class MiGA::Taxonomy < MiGA::MiGA
96
98
  end
97
99
 
98
100
  ##
99
- # Removes (and returns) all alternative taxonomies.
101
+ # Removes (and returns) all alternative taxonomies.
100
102
  def delete_alternative
101
103
  alt = @alt.dup
102
104
  @alt = []
@@ -109,6 +111,7 @@ class MiGA::Taxonomy < MiGA::MiGA
109
111
  def in?(taxon)
110
112
  r = taxon.ranks.keys.first
111
113
  return false if self[r].nil?
114
+
112
115
  self[r].casecmp(taxon[r]).zero?
113
116
  end
114
117
 
@@ -120,6 +123,7 @@ class MiGA::Taxonomy < MiGA::MiGA
120
123
  @@KNOWN_RANKS.map do |r|
121
124
  next if
122
125
  (r == :ns && !with_namespace) || (ranks[r].nil? && !force_ranks)
126
+
123
127
  [r, ranks[r]]
124
128
  end.compact
125
129
  end
@@ -179,6 +183,7 @@ class MiGA::Taxonomy < MiGA::MiGA
179
183
  unless ranks.size == str.size
180
184
  raise "Unequal number of ranks and names: #{ranks} => #{str}"
181
185
  end
186
+
182
187
  str.each_with_index { |i, k| self << "#{ranks[k]}:#{i}" }
183
188
  end
184
189
  end