Taxonomic hierarchy Hash.
# File lib/miga/taxonomy/base.rb, line 28 def KNOWN_RANKS() @@KNOWN_RANKS end
# File lib/miga/taxonomy/base.rb, line 32 def LONG_RANKS() @@LONG_RANKS end
Initialize from JSON-derived Hash o
# File lib/miga/taxonomy/base.rb, line 24 def json_create(o) new(o['str'], nil, o['alt']) end
Create MiGA::Taxonomy from String or Array str
. The string is a
series of space-delimited entries, the array is a vector of entries. Each
entry can be either a rank:value pair (if ranks
is nil), or
just values in the same order as ther ranks in ranks
.
Alternatively, str
as a Hash with rank => value pairs is
also supported. If alt
is passed, it must be an Array of String, Array, or Hash entries as defined above
(except ranks
are not allowed).
# File lib/miga/taxonomy.rb, line 23 def initialize(str, ranks = nil, alt = []) reset(str, ranks) @alt = (alt || []).map { |i| Taxonomy.new(i) } end
Returns cannonical rank (Symbol) for the rank
String
# File lib/miga/taxonomy/base.rb, line 8 def normalize_rank(rank) return unless rank return rank.to_sym if @@_KNOWN_RANKS_H[rank.to_sym] rank = rank.to_s.downcase return if rank == 'no rank' rank = @@RANK_SYNONYMS[rank] unless @@RANK_SYNONYMS[rank].nil? rank = rank.to_sym return unless @@_KNOWN_RANKS_H[rank] rank end
Add value
to the hierarchy, that can be an Array, a String, or a Hash, as described in initialize.
# File lib/miga/taxonomy.rb, line 43 def <<(value) case value when Hash value.each do |r, n| next if n.nil? || n == '' @ranks[self.class.normalize_rank(r)] = n.tr('_', ' ') end when Array value.each { |v| self << v } when String self << Hash[*value.split(':', 2)] else raise 'Unsupported class: ' + value.class.name end end
Get rank
value.
# File lib/miga/taxonomy.rb, line 62 def [](rank) @ranks[rank.to_sym] end
Add an alternative taxonomy. If the namespace matches an existing
namespace, the alternative (or master) is replaced instead if
replace
is true.
# File lib/miga/taxonomy.rb, line 91 def add_alternative(tax, replace = true) return if tax.nil? raise 'Unsupported taxonomy class.' unless tax.is_a? MiGA::Taxonomy alt_ns = alternative(tax.namespace) if !replace || tax.namespace.nil? || alt_ns.nil? @alt << tax else alt_ns.reset(tax.to_s) end end
Get the alternative taxonomies.
If which
is nil (default), returns all alternative taxonomies
as Array (not including the master taxonomy).
If which
is Integer, returns the indexed taxonomy (starting
with 0, the master taxonomy).
Otherwise, returns the first taxonomy with namespace which
(coerced as String), including the master
taxonomy.
In the latter two cases it can be nil.
# File lib/miga/taxonomy.rb, line 77 def alternative(which = nil) case which when nil @alt when Integer ([self] + @alt)[which] else ([self] + @alt).find { |i| i.namespace.to_s == which.to_s } end end
Removes (and returns) all alternative taxonomies.
# File lib/miga/taxonomy.rb, line 105 def delete_alternative alt = @alt.dup @alt = [] alt end
Domain of the taxonomy (a String) or
nil
# File lib/miga/taxonomy.rb, line 142 def domain self[:d] end
Generate a duplicate of the current object
# File lib/miga/taxonomy.rb, line 180 def dup self.class.new(to_s, nil, alternative.map(&:dup)) end
Get the most general rank as a two-entry Array (rank and value). If
force_ranks
is true, it always returns the value for domain
(d) even if undefined.
# File lib/miga/taxonomy.rb, line 150 def highest(force_ranks = false) sorted_ranks(force_ranks).first end
Evaluates if the loaded taxonomy includes taxon
. It assumes
that taxon
only has one informative rank. The evaluation is
case-insensitive.
# File lib/miga/taxonomy.rb, line 114 def in?(taxon) r = taxon.ranks.keys.first return false if self[r].nil? self[r].casecmp(taxon[r]).zero? end
Get the most specific rank as a two-entry Array (rank and value). If
force_ranks
is true, it always returns the value for dataset
(ds) even if undefined.
# File lib/miga/taxonomy.rb, line 158 def lowest(force_ranks = false) sorted_ranks(force_ranks).last end
Namespace of the taxonomy (a String) or
nil
.
# File lib/miga/taxonomy.rb, line 136 def namespace self[:ns] end
Reset ranks (including namespace) while leaving alternatives untouched. See
initialize for str
and ranks
.
# File lib/miga/taxonomy.rb, line 31 def reset(str, ranks = nil) @ranks = {} if ranks.nil? initialize_by_str(str) else initialize_by_ranks(str, ranks) end end
Sorted list of ranks, as an Array of two-entry Arrays (rank and value). If
force_ranks
is true, it returns all standard ranks even if
undefined. If with_namespace
is true, it includes also the
namespace.
# File lib/miga/taxonomy.rb, line 125 def sorted_ranks(force_ranks = false, with_namespace = false) @@KNOWN_RANKS.map do |r| next if (r == :ns && !with_namespace) || (ranks[r].nil? && !force_ranks) [r, ranks[r]] end.compact end
Generate JSON-formated String representing the taxonomy.
# File lib/miga/taxonomy.rb, line 172 def to_json(*a) hsh = { JSON.create_id => self.class.name, 'str' => to_s } hsh['alt'] = alternative.map(&:to_s) unless alternative.empty? hsh.to_json(*a) end
Generate cannonical String for the taxonomy.
If force_ranks
is true, it returns all the standard ranks even
if undefined.
# File lib/miga/taxonomy.rb, line 165 def to_s(force_ranks = false) sorted_ranks(force_ranks, true) .map { |r| "#{r[0]}:#{(r[1] || '').gsub(/[\s:]/, '_')}" }.join(' ') end