Module: CollectionObject::DwcExtensions

Extended by:
ActiveSupport::Concern
Included in:
CollectionObject, BiologicalCollectionObject
Defined in:
app/models/collection_object/dwc_extensions.rb

Instance Method Summary collapse

Instance Method Details

TODO: likeley a helper



137
138
139
140
141
142
143
144
145
146
# File 'app/models/collection_object/dwc_extensions.rb', line 137

def api_image_link(image)
  s = ENV['SERVER_NAME']
  if s.nil?
    s ||= 'http://127.0.0.1:3000'
  else
    s = 'https://' + s
  end

  s = s + '/api/v1/images/' + image.image_file_fingerprint # An experiment, use md5 as a proxy for id (also unique id)
end

#dwc_associated_mediaObject



132
133
134
# File 'app/models/collection_object/dwc_extensions.rb', line 132

def dwc_associated_media
  images.collect{|i| api_image_link(i) }.join(CollectionObject::DWC_DELIMITER).presence
end

#dwc_catalog_numberObject



388
389
390
# File 'app/models/collection_object/dwc_extensions.rb', line 388

def dwc_catalog_number
  catalog_number_cached # via delegation
end

#dwc_coordinate_uncertainty_in_metersObject

TODO: extend to Georeferences when we understand how to describe spatial uncertainty



183
184
185
186
187
188
189
# File 'app/models/collection_object/dwc_extensions.rb', line 183

def dwc_coordinate_uncertainty_in_meters
  if georeference_attributes[:coordinateUncertaintyInMeters]
    georeference_attributes[:coordinateUncertaintyInMeters]
  else
    collecting_event&.verbatim_geolocation_uncertainty
  end
end

#dwc_countryObject



397
398
399
400
# File 'app/models/collection_object/dwc_extensions.rb', line 397

def dwc_country
  v = try(:collecting_event).try(:geographic_names)
  v[:country] if v
end

#dwc_countyObject



407
408
409
410
# File 'app/models/collection_object/dwc_extensions.rb', line 407

def dwc_county
  v = try(:collecting_event).try(:geographic_names)
  v[:county] if v
end

#dwc_date_identifiedObject

ISO 8601:2004(E).



313
314
315
# File 'app/models/collection_object/dwc_extensions.rb', line 313

def dwc_date_identified
  current_taxon_determination&.date.presence
end

#dwc_decimal_latitudeObject



416
417
418
# File 'app/models/collection_object/dwc_extensions.rb', line 416

def dwc_decimal_latitude
  georeference_attributes[:decimalLatitude]
end

#dwc_decimal_longitudeObject



420
421
422
# File 'app/models/collection_object/dwc_extensions.rb', line 420

def dwc_decimal_longitude
  georeference_attributes[:decimalLongitude]
end

#dwc_event_dateObject



445
446
447
448
449
450
451
452
453
454
455
456
# File 'app/models/collection_object/dwc_extensions.rb', line 445

def dwc_event_date
  return unless collecting_event

  %w{start_date end_date}
    .map { |d| %w{year month day}
    .map { |p| collecting_event["#{d}_#{p}"] }
    .map { |p| "%02d" % p if p } # At least two digits
    }
      .map { |d| d.compact.join('-') }
      .reject(&:blank?)
      .join("/").presence
end

#dwc_event_timeObject



432
433
434
435
436
437
438
439
440
441
442
443
# File 'app/models/collection_object/dwc_extensions.rb', line 432

def dwc_event_time
  return unless collecting_event

  %w{start_time end_time}
    .map { |t| %w{hour minute second}
    .map { |p| collecting_event["#{t}_#{p}"] }
    .map { |p| "%02d" % p if p } # At least two digits
    }
      .map { |t| t.compact.join(':') }
      .reject(&:blank?)
      .join("/").presence
end

#dwc_familyObject



322
323
324
# File 'app/models/collection_object/dwc_extensions.rb', line 322

def dwc_family
  taxonomy['family']
end

#dwc_field_numberObject



281
282
283
284
# File 'app/models/collection_object/dwc_extensions.rb', line 281

def dwc_field_number
  return nil unless collecting_event
  collecting_event.identifiers.where(type: 'Identifier::Local::TripCode').first&.cached
end

#dwc_footprint_wktObject



156
157
158
# File 'app/models/collection_object/dwc_extensions.rb', line 156

def dwc_footprint_wkt
  georeference_attributes[:footprintWKT]
end

#dwc_genusObject



327
328
329
# File 'app/models/collection_object/dwc_extensions.rb', line 327

def dwc_genus
  taxonomy['genus'] && taxonomy['genus'].compact.join(' ').presence
end

#dwc_geodetic_datumObject



168
169
170
# File 'app/models/collection_object/dwc_extensions.rb', line 168

def dwc_geodetic_datum
  georeference_attributes[:geodeticDatum]
end

#dwc_georeference_protocolObject



472
473
474
# File 'app/models/collection_object/dwc_extensions.rb', line 472

def dwc_georeference_protocol
  georeference_attributes[:georeferenceProtocol]
end

#dwc_georeference_remarksObject



152
153
154
# File 'app/models/collection_object/dwc_extensions.rb', line 152

def dwc_georeference_remarks
  georeference_attributes[:georeferenceRemarks]
end

#dwc_georeference_sourcesObject



148
149
150
# File 'app/models/collection_object/dwc_extensions.rb', line 148

def dwc_georeference_sources
  georeference_attributes[:georeferenceSources]
end

#dwc_georeferenced_byObject



160
161
162
# File 'app/models/collection_object/dwc_extensions.rb', line 160

def dwc_georeferenced_by
  georeference_attributes[:georeferencedBy]
end

#dwc_georeferenced_dateObject

georeferenceDate technically could look at papertrail to see when geographic_area_id appeared



178
179
180
# File 'app/models/collection_object/dwc_extensions.rb', line 178

def dwc_georeferenced_date
  georeference_attributes[:georeferencedDate]
end

#dwc_identified_byObject



374
375
376
377
# File 'app/models/collection_object/dwc_extensions.rb', line 374

def dwc_identified_by
  # TaxonWorks allows for groups of determiners to collaborate on a single determination if they collectively came to a conclusion.
  current_taxon_determination&.determiners&.map(&:cached)&.join(CollectionObject::DWC_DELIMITER).presence
end

#dwc_identified_by_idObject



379
380
381
382
# File 'app/models/collection_object/dwc_extensions.rb', line 379

def dwc_identified_by_id
  # TaxonWorks allows for groups of determiners to collaborate on a single determination if they collectively came to a conclusion.
  current_taxon_determination&.determiners&.map(&:orcid)&.join(CollectionObject::DWC_DELIMITER).presence
end

#dwc_individual_countObject

TODO: handle ranged lots



393
394
395
# File 'app/models/collection_object/dwc_extensions.rb', line 393

def dwc_individual_count
  total
end

#dwc_infraspecific_epithetObject



294
295
296
297
298
299
# File 'app/models/collection_object/dwc_extensions.rb', line 294

def dwc_infraspecific_epithet
  %w{variety form subspecies}.each do |n| # add more as observed
    return taxonomy[n].last if taxonomy[n]
  end
  nil
end

#dwc_institution_codeObject

we assert custody, NOT ownership



463
464
465
# File 'app/models/collection_object/dwc_extensions.rb', line 463

def dwc_institution_code
  repository.try(:acronym)
end

#dwc_institution_idObject

we assert custody, NOT ownership



468
469
470
# File 'app/models/collection_object/dwc_extensions.rb', line 468

def dwc_institution_id
  repository_url
end

#dwc_internal_attribute_for(target = :collection_object, dwc_term_name) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'app/models/collection_object/dwc_extensions.rb', line 211

def dwc_internal_attribute_for(target = :collection_object, dwc_term_name)
  return nil if dwc_term_name.nil?

  case target
  when  :collecting_event
    return nil unless collecting_event
    collecting_event.internal_attributes.includes(:predicate)
      .where(
        controlled_vocabulary_terms: {uri: ::DWC_ATTRIBUTE_URIS[dwc_term_name.to_sym] })
      .pluck(:value)&.join(', ').presence
  when :collection_object
    internal_attributes.includes(:predicate)
      .where(
        controlled_vocabulary_terms: {uri: ::DWC_ATTRIBUTE_URIS[dwc_term_name.to_sym] })
      .pluck(:value)&.join(', ').presence
  else
    nil
  end
end

#dwc_kingdomObject



317
318
319
# File 'app/models/collection_object/dwc_extensions.rb', line 317

def dwc_kingdom
  taxonomy['kingdom']
end

#dwc_life_stageObject

TODO: consider CVT attributes with Predicates linked to URIs



248
249
250
251
# File 'app/models/collection_object/dwc_extensions.rb', line 248

def dwc_life_stage
  biocuration_classes.tagged_with_uri(::DWC_ATTRIBUTE_URIS[:lifeStage])
    .pluck(:name)&.join(', ').presence # `.presence` is a Rails extension
end

#dwc_localityObject



412
413
414
# File 'app/models/collection_object/dwc_extensions.rb', line 412

def dwc_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_maximum_depth_in_metersObject



239
240
241
# File 'app/models/collection_object/dwc_extensions.rb', line 239

def dwc_maximum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :maximumDepthInMeters)
end

#dwc_maximum_elevation_in_metersObject



268
269
270
# File 'app/models/collection_object/dwc_extensions.rb', line 268

def dwc_maximum_elevation_in_meters
  collecting_event&.maximum_elevation
end

#dwc_minimum_depth_in_metersObject



235
236
237
# File 'app/models/collection_object/dwc_extensions.rb', line 235

def dwc_minimum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :minimumDepthInMeters)
end

#dwc_minimum_elevation_in_metersObject



272
273
274
# File 'app/models/collection_object/dwc_extensions.rb', line 272

def dwc_minimum_elevation_in_meters
  collecting_event&.minimum_elevation
end

#dwc_nomenclatural_codeObject



428
429
430
# File 'app/models/collection_object/dwc_extensions.rb', line 428

def dwc_nomenclatural_code
  current_otu.try(:taxon_name).try(:nomenclatural_code)
end

#dwc_other_catalog_numbersObject



199
200
201
202
203
# File 'app/models/collection_object/dwc_extensions.rb', line 199

def dwc_other_catalog_numbers
  i = identifiers.where.not('type ilike ?', 'Identifier::Global::Uuid%').order(:position).to_a
  i.shift
  i.map(&:cached).join(CollectionObject::DWC_DELIMITER).presence
end

#dwc_preparationsObject



458
459
460
# File 'app/models/collection_object/dwc_extensions.rb', line 458

def dwc_preparations
  preparation_type_name
end

#dwc_previous_identificationsObject



205
206
207
208
209
# File 'app/models/collection_object/dwc_extensions.rb', line 205

def dwc_previous_identifications
  a = taxon_determinations.order(:position).to_a
  a.shift
  a.collect{|d| ApplicationController.helpers.label_for_taxon_determination(d)}.join(CollectionObject::DWC_DELIMITER).presence
end

#dwc_recorded_byObject

Definition: A list (concatenated and separated) of names of people, groups, or organizations responsible for recording the original Occurrence. The primary collector or observer, especially one who applies a personal identifier (recordNumber), should be listed first.

This was interpreted as collectors (in the field in this context), not those who recorded other aspectes of the data.



347
348
349
350
351
352
353
354
355
356
357
358
# File 'app/models/collection_object/dwc_extensions.rb', line 347

def dwc_recorded_by
  v = nil
  if collecting_event
    v = collecting_event.collectors
      .order('roles.position')
      .pluck(:cached)
      .join(CollectionObject::DWC_DELIMITER)
      .presence
    v = collecting_event.verbatim_collectors.presence if v.blank?
  end
  v
end

#dwc_recorded_by_idObject

See dwc_recorded_by



361
362
363
364
365
366
367
368
369
370
371
372
# File 'app/models/collection_object/dwc_extensions.rb', line 361

def dwc_recorded_by_id

  if collecting_event
    collecting_event.collectors
      .order('roles.position')
      .map(&:orcid)
      .compact
      .join(CollectionObject::DWC_DELIMITER)
      .presence
  end

end

#dwc_sampling_protocolObject

TODO: Reconcile with Protocol (capital P) assignments



277
278
279
# File 'app/models/collection_object/dwc_extensions.rb', line 277

def dwc_sampling_protocol
  collecting_event&.verbatim_method
end

#dwc_scientific_nameObject



336
337
338
# File 'app/models/collection_object/dwc_extensions.rb', line 336

def dwc_scientific_name
  current_taxon_name.try(:cached_name_and_author_year)
end

#dwc_sexObject

TODO: consider CVT attributes with Predicates linked to URIs



254
255
256
257
# File 'app/models/collection_object/dwc_extensions.rb', line 254

def dwc_sex
  biocuration_classes.tagged_with_uri(::DWC_ATTRIBUTE_URIS[:sex])
    .pluck(:name)&.join(', ').presence
end

#dwc_specific_epithetObject



332
333
334
# File 'app/models/collection_object/dwc_extensions.rb', line 332

def dwc_specific_epithet
  taxonomy['species'] && taxonomy['species'].compact.join(' ').presence
end

#dwc_state_provinceObject



402
403
404
405
# File 'app/models/collection_object/dwc_extensions.rb', line 402

def dwc_state_province
  v = try(:collecting_event).try(:geographic_names)
  v[:state] if v
end

#dwc_taxon_name_authorshipObject



340
341
342
# File 'app/models/collection_object/dwc_extensions.rb', line 340

def dwc_taxon_name_authorship
  current_taxon_name.try(:cached_author_year)
end

#dwc_taxon_rankObject



301
302
303
# File 'app/models/collection_object/dwc_extensions.rb', line 301

def dwc_taxon_rank
  current_taxon_name&.rank
end

#dwc_type_statusObject

holotype of Ctenomys sociabilis. Pearson O. P., and M. I. Christie. 1985. Historia Natural, 5(37):388, holotype of Pinus abies | holotype of Picea abies



306
307
308
309
310
# File 'app/models/collection_object/dwc_extensions.rb', line 306

def dwc_type_status
  type_materials.all.collect{|t|
    ApplicationController.helpers.label_for_type_material(t)
  }.join(CollectionObject::DWC_DELIMITER).presence
end

#dwc_verbatim_coordinatesObject



259
260
261
262
# File 'app/models/collection_object/dwc_extensions.rb', line 259

def dwc_verbatim_coordinates
  return nil unless collecting_event
  [collecting_event.verbatim_latitude, collecting_event.verbatim_longitude].compact.join(' ').presence
end

#dwc_verbatim_depthObject



243
244
245
# File 'app/models/collection_object/dwc_extensions.rb', line 243

def dwc_verbatim_depth
  dwc_internal_attribute_for(:collecting_event, :verbatimDepth)
end

#dwc_verbatim_elevationObject



264
265
266
# File 'app/models/collection_object/dwc_extensions.rb', line 264

def dwc_verbatim_elevation
  collecting_event&.verbatim_elevation
end

#dwc_verbatim_event_dateObject



290
291
292
# File 'app/models/collection_object/dwc_extensions.rb', line 290

def dwc_verbatim_event_date
  collecting_event&.verbatim_date
end

#dwc_verbatim_habitatObject



286
287
288
# File 'app/models/collection_object/dwc_extensions.rb', line 286

def dwc_verbatim_habitat
  collecting_event&.verbatim_habitat
end

#dwc_verbatim_latitudeObject



191
192
193
# File 'app/models/collection_object/dwc_extensions.rb', line 191

def dwc_verbatim_latitude
  collecting_event&.verbatim_latitude
end

#dwc_verbatim_localityObject



424
425
426
# File 'app/models/collection_object/dwc_extensions.rb', line 424

def dwc_verbatim_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_verbatim_longitudeObject



195
196
197
# File 'app/models/collection_object/dwc_extensions.rb', line 195

def dwc_verbatim_longitude
  collecting_event&.verbatim_longitude
end

#dwc_verbatim_srsObject



172
173
174
# File 'app/models/collection_object/dwc_extensions.rb', line 172

def dwc_verbatim_srs
  georeference_attributes[:dwcVerbatimSrs]
end

#dwc_water_bodyObject



231
232
233
# File 'app/models/collection_object/dwc_extensions.rb', line 231

def dwc_water_body
  dwc_internal_attribute_for(:collecting_event, :waterBody)
end

#set_georeference_attributesHash

Returns:

  • (Hash)


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
# File 'app/models/collection_object/dwc_extensions.rb', line 101

def set_georeference_attributes
  case collecting_event&.dwc_georeference_source
  when :georeference
    collecting_event.preferred_georeference.dwc_georeference_attributes
  when :verbatim
    h = collecting_event.dwc_georeference_attributes

    if a = collecting_event&.attribute_updater(:verbatim_latitude)
      h[:georeferencedBy] = User.find(a).name
    end

    # verbatim_longitude could technically be different, but...
    h[:georeferencedDate] = collecting_event&.attribute_updated(:verbatim_latitude)

    h

  when :geographic_area
    h = collecting_event.geographic_area.dwc_georeference_attributes
    if a = collecting_event&.attribute_updater(:geographic_area_id)
      h[:georeferencedBy] = User.find(a).name
    end

    h[:georeferencedDate] = collecting_event&.attribute_updated(:geographic_area_id)

    h
  else
    {}
  end
end