Class: BatchLoad::Import::TaxonNames::NomenInterpreter

Inherits:
BatchLoad::Import show all
Defined in:
lib/batch_load/import/taxon_names/nomen_interpreter.rb

Constant Summary collapse

SAVE_ORDER =
[:original_taxon_name, :taxon_name, :taxon_name_relationship, :otu]

Instance Attribute Summary collapse

Attributes inherited from BatchLoad::Import

#create_attempted, #csv, #errors, #file, #file_errors, #import_level, #processed, #processed_rows, #project, #successful_rows, #total_data_lines, #total_lines, #user, #user_header_map, #user_id

Instance Method Summary collapse

Methods inherited from BatchLoad::Import

#all_objects, #create, #create_attempted?, #import_level_ok?, #line_strict_level_ok?, #processed?, #ready_to_create?, #save_order, #sorted_processed_rows, #strict_level_ok?, #total_records_created, #user_map, #valid?, #valid_objects, #warn_level_ok?

Constructor Details

#initialize(nomenclature_code: nil, parent_taxon_name_id: nil, also_create_otu: false, **args) ⇒ NomenInterpreter

Returns a new instance of NomenInterpreter.

Parameters:

  • args (Hash)


23
24
25
26
27
28
29
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 23

def initialize(nomenclature_code: nil, parent_taxon_name_id: nil, also_create_otu: false, **args)
  @nomenclature_code = nomenclature_code.presence
  @parent_taxon_name_id = parent_taxon_name_id.presence
  @also_create_otu = also_create_otu.presence

  super(**args)
end

Instance Attribute Details

#also_create_otuObject

Whether to create an OTU as well

Returns:

  • Boolean



15
16
17
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 15

def also_create_otu
  @also_create_otu
end

#base_taxon_name_idObject

The default parent if otherwise not provided



8
9
10
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 8

def base_taxon_name_id
  @base_taxon_name_id
end

#nomenclature_codeObject

The code (Rank Class) that new names will use. Required.



11
12
13
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 11

def nomenclature_code
  @nomenclature_code
end

#parent_taxon_name_idObject

The id of the parent taxon name, computed automatically as Root if not provided



5
6
7
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 5

def parent_taxon_name_id
  @parent_taxon_name_id
end

#project_idObject

Required to handle some defaults



18
19
20
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 18

def project_id
  @project_id
end

Instance Method Details

#buildBoolean

Returns:

  • (Boolean)


201
202
203
204
205
206
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 201

def build
  if valid?
    build_taxon_names
    @processed = true
  end
end

#build_taxon_namesInteger

rubocop:disable Metrics/MethodLength

Returns:

  • (Integer)


50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 50

def build_taxon_names
  @total_data_lines = 0
  i = 0
  taxon_names = {}

  csv.each_with_index do |row, i|

    parse_result = BatchLoad::RowParse.new
    parse_result.row_number = i # check vs. header etc.

    parse_result.objects[:original_taxon_name] = []
    parse_result.objects[:taxon_name] = []
    parse_result.objects[:taxon_name_relationship] = []
    parse_result.objects[:otu] = []

    @processed_rows[i] = parse_result

    begin
      next if ['complex', 'species group', 'series', 'variety', 'unidentified'].include?(row['rank'])

      rank = Ranks.lookup(@nomenclature_code.to_sym, row['rank'])

      parse_result.parse_errors.push 'Unknown rank.' if rank.blank?

      protonym_attributes = {
        name: row['taxon_name'],
        year_of_publication: year_of_publication(row['author_year']),
        rank_class: rank,
        by: user,
        project:,
        verbatim_author: verbatim_author(row['author_year']),

        # People are not created at this point
        #  taxon_name_authors_attributes: taxon_name_authors_attributes(verbatim_author(row['author_year']))
      }

      # Not implemented

      # if row['original_name']
      #   original_protonym_attributes = {
      #     verbatim_name: row['original_name'],
      #     name: row['original_name'].split(' ')[-1],
      #     year_of_publication: year_of_publication(row['author_year']),
      #     rank_class: Ranks.lookup(@nomenclature_code.to_sym, row['original_rank']),
      #     parent: parent_taxon_name,
      #     by: user,
      #     project:,
      #     verbatim_author: verbatim_author(row['author_year']),
      #     taxon_name_authors_attributes: taxon_name_authors_attributes(verbatim_author(row['author_year']))
      #   }

      #   original_protonym = Protonym.new(original_protonym_attributes)

      #   if row['original_rank'] == 'genus'
      #     protonym_attributes[:original_genus] = original_protonym
      #   elsif row['original_rank'] == 'subgenus'
      #     protonym_attributes[:original_subgenus] = original_protonym
      #   elsif row['original_rank'] == 'species'
      #     protonym_attributes[:original_species] = original_protonym
      #   elsif row['original_rank'] == 'subspecies'
      #     protonym_attributes[:original_subspecies] = original_protonym
      #   end

      #   parse_result.objects[:original_taxon_name].push original_protonym
      # end

      p = Protonym.new(protonym_attributes)

      # row data
      taxon_name_id = row['id']
      parent_id = row['parent_id']

      taxon_names[taxon_name_id] = p

      if parent_id.blank?
        p.parent_id = parent_taxon_name_id
      else
        if taxon_names[parent_id]
          p.parent = taxon_names[parent_id]
        else
          parse_result.parse_errors.push 'Parent ID is not defined at this point! Row out of order?'
        end
      end

      # TaxonNameRelationship
      related_name_id = row['related_name_id']

      if taxon_names[related_name_id].present?
        related_name_nomen_class = nil

        begin
          related_name_nomen_class = row['related_name_nomen_class'].safe_constantize

          if related_name_nomen_class.ancestors.include?(TaxonNameRelationship)

            taxon_name_relationship = related_name_nomen_class.new(
              subject_taxon_name: p, object_taxon_name: taxon_names[related_name_id]
            )

            parse_result.objects[:taxon_name_relationship].push taxon_name_relationship
          end
        rescue NameError
          parse_result.parse_errors.push 'Unknown taxon name relationship'
        end
      end

      # TaxonNameClassification

      # TODO: add to index, not here
      if name_nomen_classification = row['name_nomen_classification']
        begin
          if c = name_nomen_classification.safe_constantize
            p.taxon_name_classifications_attributes = [ {type: name_nomen_classification} ]
          end
        rescue NameError
          parse_result.parse_errors.push 'Unknown taxon name classification'
        end
      end

      # There is an OTU linked to the taxon name.
      if row['taxon_concept_name'].present? || row['guid'].present?
        taxon_concept_identifier_nomen = {}

        if row['guid'].present?
          taxon_concept_identifier_nomen = {
            type: 'Identifier::Global::Uri',
            identifier: row['guid'] }
        end

        otu = Otu.new(name: row['taxon_concept_name'], taxon_name: p, identifiers_attributes: [taxon_concept_identifier_nomen] )

        parse_result.objects[:otu].push(otu)
      else

        # Note we are not technically using the param like TaxonName.new(), so we can't just set the attribute
        # So we hack in the OTUs 'manually".  This also lets us see them in the result
        if also_create_otu
          parse_result.objects[:otu].push Otu.new(taxon_name: p)
        end
      end

      parse_result.objects[:taxon_name].push p
      @total_data_lines += 1 if p.present?
    end
  end

  @total_lines = i
end

#root_taxon_nameString

Returns:

  • (String)


41
42
43
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 41

def root_taxon_name
  Project.find(@project_id).root_taxon_name
end

#verbatim_author(author_year) ⇒ String? (private)

TODO: unify parsing to somewhere else

Parameters:

  • author_year (String)

Returns:

  • (String, nil)

    just the author name, wiht parens left on



220
221
222
223
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 220

def verbatim_author(author_year)
  return nil if author_year.blank?
  author_year.gsub(/\,+\s*\d\d\d\d/, '')
end

#year_of_publication(author_year) ⇒ String? (private)

Parameters:

  • author_year (String)

Returns:

  • (String, nil)


212
213
214
215
# File 'lib/batch_load/import/taxon_names/nomen_interpreter.rb', line 212

def year_of_publication(author_year)
  return nil if author_year.blank?
  author_year&.match(/\d\d\d\d/)&.to_s
end