Class: Taxonifi::Model::NameCollection

Inherits:
Collection
  • Object
show all
Defined in:
lib/taxonifi/model/name_collection.rb

Overview

A collection of taxonomic names.

Instance Attribute Summary collapse

Attributes inherited from Collection

#by_id_index, #collection, #current_free_id

Instance Method Summary collapse

Methods inherited from Collection

#children_of_object, #object_by_id, #objects_without_parents, #parent_id_vector, subclass_prefixes

Methods included from SharedClassMethods

included

Constructor Details

#initialize(options = {}) ⇒ NameCollection

Returns a new instance of NameCollection.



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/taxonifi/model/name_collection.rb', line 48

def initialize(options = {})
  super 
  @by_name_index = {'genus_group' => {}, 'species_group' => {}, 'unknown' => {}}     # Lumping species and genus group names, unranked named are in 'unknown'
  Taxonifi::RANKS[0..-5].inject(@by_name_index){|hsh, v| hsh.merge!(v => {})}        # TODO: Still needed?! 
  @ref_collection = options[:ref_collection]
  @citations = {} 
  @combinations = []
  @nomenclators = {} 
  @nomenclator_index = options[:initial_nomenclator_index] 
  @nomenclator_index ||= 1
  @duplicate_entry_buffer = {} # Move to Collection?!
  true
end

Instance Attribute Details

#by_name_indexObject

A Hash. Keys are the name (String), values are ids of Names in the collection. { rank => { name => [ids] }} There are two special ranks “genus_group” and “species_group”. E.g.: => {‘bar’ => [1,2,93]})



15
16
17
# File 'lib/taxonifi/model/name_collection.rb', line 15

def by_name_index
  @by_name_index
end

#citationsObject

TaxonNameID => [[ nomenclator_index, Ref ], … []]



46
47
48
# File 'lib/taxonifi/model/name_collection.rb', line 46

def citations
  @citations
end

#combinationsObject

An optional collection of existing combinations of species names, as represented by individual arrays of Taxonifi::Model::Names. Note you can not use a Taxonifi::Model::SpeciesName for this purpose because getting/setting names therin will affect other combinations TODO: DEPRECATE? !?!



24
25
26
# File 'lib/taxonifi/model/name_collection.rb', line 24

def combinations
  @combinations
end

#duplicate_entry_bufferObject

A Hash. Contains metadata when non-unique names are found in input parsing row identifier => { redundant row identifier => {properties hash}} TODO: reconsider, move to superclass or down to record base TODO: Test



30
31
32
# File 'lib/taxonifi/model/name_collection.rb', line 30

def duplicate_entry_buffer
  @duplicate_entry_buffer
end

#nomenclator_indexObject

An Integer used for indexing nomenclator records in @nomenclators. Contains the next available index value.



43
44
45
# File 'lib/taxonifi/model/name_collection.rb', line 43

def nomenclator_index
  @nomenclator_index
end

#nomenclatorsObject

A Hash. Index (keys) created by the collection, values are an Array of Strings representing the genus, subgenus, species, and subspecies name. Automatically populated when .add_object is used. Alternately populated with .add_nomenclator(Name) Nomenclator values are not repeated.

Index is used in @citations. { @nomenclator_index => [genus_string, subgenus_string, species_string, subspecies_string, infrasubspecific_string (e.g. variety)], … } !! The names represented in the Array of strings does NOT have to be represented in the NameCollection.



40
41
42
# File 'lib/taxonifi/model/name_collection.rb', line 40

def nomenclators
  @nomenclators
end

#ref_collectionObject

A Taxonifi::Model::RefCollection, optionally generated from Author/Year strings



18
19
20
# File 'lib/taxonifi/model/name_collection.rb', line 18

def ref_collection
  @ref_collection
end

Instance Method Details

#add_citation(name, ref, nomenclator_index, properties) ⇒ Object

Add a Citation Returns the index of the Nomenclator added. TODO: Test/Validate



166
167
168
169
170
171
172
173
174
# File 'lib/taxonifi/model/name_collection.rb', line 166

def add_citation(name, ref, nomenclator_index, properties)
  if @citations[name.id]
    return false if @citations[name.id].collect{|i| [i[0],i[1]] }.include?([ref.id, nomenclator_index])
    @citations[name.id].push([ref.id, nomenclator_index, properties])
  else
    @citations[name.id] = [[ref.id, nomenclator_index, properties]]
  end
  true
end

#add_duplicate_entry_metadata(name_id, row_identifier, data_hash) ⇒ Object

Add a record to @duplicate_entry_buffer



252
253
254
255
# File 'lib/taxonifi/model/name_collection.rb', line 252

def (name_id, row_identifier, data_hash)
  @duplicate_entry_buffer[name_id] = Hash.new if !@duplicate_entry_buffer[name_id]
  @duplicate_entry_buffer[name_id].merge!(row_identifier => data_hash)
end

#add_nomenclator(nomenclator_array) ⇒ Object

Add a Nomenclator (Array) to the index. Returns the index of the Nomenclator added. TODO: Test



147
148
149
150
151
152
153
154
155
156
# File 'lib/taxonifi/model/name_collection.rb', line 147

def add_nomenclator(nomenclator_array)
  raise if (!nomenclator_array.class == Array) || (nomenclator_array.length != 5)
  if @nomenclators.has_value?(nomenclator_array)
    return @nomenclators.key(nomenclator_array) 
  else
    @nomenclators.merge!(@nomenclator_index => nomenclator_array) 
    @nomenclator_index += 1
    return @nomenclator_index - 1
  end
end

#add_object(obj) ⇒ Object

Add an individual Name instance, indexing it.



123
124
125
126
127
128
# File 'lib/taxonifi/model/name_collection.rb', line 123

def add_object(obj)
  super
  index_by_name(obj)
  derive_nomenclator(obj) if obj.nomenclator_name?
  obj
end

#add_object_pre_indexed(obj) ⇒ Object

Add an individaul Name instance, without indexing it.



131
132
133
134
135
# File 'lib/taxonifi/model/name_collection.rb', line 131

def add_object_pre_indexed(obj)
  super
  index_by_name(obj)
  obj
end

#add_original_genus_id_propertyObject

For all species group names, assigns to property ‘original_genus_id’ the id of the parent genus group name if parens are not set. Returns an Array of ids for those names for which the property has NOT been set.



259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/taxonifi/model/name_collection.rb', line 259

def add_original_genus_id_property
  not_added = [] 
  by_name_index['species_group'].values.flatten.uniq.each do |id|
    name = object_by_id(id) 
    if name.parens != true
      name.add_property('original_genus_id', name.genus_group_parent.id)
    else
      not_added.push(name.id)
    end
  end
  not_added
end

#add_species_name(sn) ⇒ Object

Add a Taxonifi::Model::SpeciesName object as individual objects.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/taxonifi/model/name_collection.rb', line 178

def add_species_name(sn)
  raise "Failed trying to load [#{sn.display_name}]. SpeciesName#genus#parent must be set before using add_species_name." if sn.genus.parent.nil?
  current_parent_id = sn.genus.parent.id 
  sn.names.each do |o|
    o.parent = object_by_id(current_parent_id)
    if id = name_exists?(o)
      cp_id = id 
    else
      add_object(o)
      cp_id = o.id
    end
    current_parent_id = cp_id
  end
  current_parent_id # return the id of the last name created
end

#add_species_name_unindexed(sn) ⇒ Object

As #add_species_name but do not assign ids to the incoming names TODO: deprecate?



197
198
199
200
201
202
203
# File 'lib/taxonifi/model/name_collection.rb', line 197

def add_species_name_unindexed(sn)
  sn.names.each do |o|
    if !name_exists?(o)
      add_object(o)
    end
  end
end

#derive_nomenclator(obj) ⇒ Object

TODO: Test



138
139
140
141
142
# File 'lib/taxonifi/model/name_collection.rb', line 138

def derive_nomenclator(obj)
  if obj.nomenclator_name? && !obj.authors.nil? && !obj.year.nil?
    add_nomenclator(obj.nomenclator_array)
  end
end

#encompassing_rankObject

Return the highest RANK for which there is no name in this collection.



72
73
74
75
76
77
78
79
# File 'lib/taxonifi/model/name_collection.rb', line 72

def encompassing_rank
  highest = RANKS.size
  @collection.each do |n|
    h = RANKS.index(n.rank)
    highest = h if h < highest
  end
  RANKS[highest - 1]
end

#generate_ref_collection(initial_id = 0) ⇒ Object

Take the author/years of these names and generate a RefCollection. Start the ids assigned to the references with initial_id.



207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/taxonifi/model/name_collection.rb', line 207

def generate_ref_collection(initial_id = 0)
  rc = Taxonifi::Model::RefCollection.new(:initial_id => initial_id)
  temp_index = {} 
  @collection.each do |n|
    index = n.author_year_index
    if !temp_index[index] && index.size > 0
      temp_index.merge!(index => nil)
      ref = Taxonifi::Model::Ref.new(authors: n.authors, year: n.year) 
      rc.add_object(ref)
    end
  end
  @ref_collection = rc 
end

#genus_group_name_stringsObject

Return an Array of Strings



273
274
275
# File 'lib/taxonifi/model/name_collection.rb', line 273

def genus_group_name_strings
  by_name_index['genus_group'].keys
end

#homonyms_at_rank(rank) ⇒ Object

Return an Array of “homonyms” within the rank provided. Useful for finding missmatched upper heirarchies, if nc is a name_collection:

homonyms = nc.homonyms_at_rank('genus')
homonyms.keys.sort.each do |n|
  puts "#{n} (#{homonyms[n].size}) :"
  homonyms[n].each do |p|
    puts "  #{p.ancestors.collect{|i| i.name}.join(",")}"
  end
end


240
241
242
243
244
245
246
247
248
249
# File 'lib/taxonifi/model/name_collection.rb', line 240

def homonyms_at_rank(rank) 
  raise if !RANKS.include?(rank)
  uniques = {}
  names_at_rank(rank).each do |n|
    uniques.merge!(n.name => []) if !uniques[n.name]
    uniques[n.name].push n
  end
  uniques.delete_if{|k| uniques[k].size < 2}
  uniques
end

#name_exists?(name = Taxonifi::Model::Name) ⇒ Boolean

Returns id of matching existing name or false if there is no match. !! assumes parent is set Matches against name, year, and all parents (by id).

!! nominotypic names are considered to be the same (species and generic). See

@combinations to instantiate these

TODO: This is likely already overly ICZN flavoured.

Returns:

  • (Boolean)


101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/taxonifi/model/name_collection.rb', line 101

def name_exists?(name = Taxonifi::Model::Name) 
  # species/genus group names are indexed for indexing purposes 
  rank = name.index_rank

  if by_name_index[rank][name.name_author_year_string]
    by_name_index[rank][name.name_author_year_string].each do |id|
      full_parent_vector = parent_id_vector(name.parent.id) 
      return id if full_parent_vector == parent_id_vector(id)  # this hits species/genus group names

      vector = parent_id_vector(id)
      next if vector.last != name.parent.id                    # can stop looking at this possiblity
      vector.pop                                               # compare just parents
      if vector == full_parent_vector 
        exists = true
        return id
      end
    end
  end 
  false 
end

#name_string_arrayObject

Return an array of the names in the collection DEPRECATE for name_strings



284
285
286
# File 'lib/taxonifi/model/name_collection.rb', line 284

def name_string_array
  collection.collect{|n| n.display_name}
end

#names_at_rank(rank) ⇒ Object

Returns an Array of the names objects in the collection at a rank. TODO: Should index this on add_object



83
84
85
86
87
88
89
90
# File 'lib/taxonifi/model/name_collection.rb', line 83

def names_at_rank(rank)
  raise if !RANKS.include?(rank)
  names = []
  @collection.each do |n|
    names << n if n.rank == rank
  end
  names
end

#nomenclator_id_for_name(name) ⇒ Object

Return the Integer (index) for a name



159
160
161
# File 'lib/taxonifi/model/name_collection.rb', line 159

def nomenclator_id_for_name(name)
  @nomenclators.key(name.nomenclator_array) 
end

#object_classObject



66
67
68
# File 'lib/taxonifi/model/name_collection.rb', line 66

def object_class
  Taxonifi::Model::Name
end

#species_group_name_stringsObject

Return an Array of Strings



278
279
280
# File 'lib/taxonifi/model/name_collection.rb', line 278

def species_group_name_strings
  by_name_index['species_group'].keys
end