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.



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

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]})



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

def by_name_index
  @by_name_index
end

#citationsObject

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



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

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? !?!



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

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



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

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.



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

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.



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

def nomenclators
  @nomenclators
end

#ref_collectionObject

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



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

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



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

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



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

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



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

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.



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

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.



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

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.



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

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.



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

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?



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

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



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

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.



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

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.



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

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



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

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


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

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)


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

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



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

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



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

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



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

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

#object_classObject



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

def object_class
  Taxonifi::Model::Name
end

#species_group_name_stringsObject

Return an Array of Strings



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

def species_group_name_strings
  by_name_index['species_group'].keys
end