Module: CollectionObject::DwcExtensions

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

Instance Method Summary collapse

Instance Method Details

TODO: likeley a helper



167
168
169
170
171
172
173
174
175
176
# File 'app/models/collection_object/dwc_extensions.rb', line 167

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



162
163
164
# File 'app/models/collection_object/dwc_extensions.rb', line 162

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

#dwc_catalog_numberObject



438
439
440
# File 'app/models/collection_object/dwc_extensions.rb', line 438

def dwc_catalog_number
  catalog_number_cached # via delegation
end

#dwc_classObject



359
360
361
# File 'app/models/collection_object/dwc_extensions.rb', line 359

def dwc_class
  taxonomy['class']
end

#dwc_collection_codeObject



434
435
436
# File 'app/models/collection_object/dwc_extensions.rb', line 434

def dwc_collection_code
  catalog_number_namespace&.verbatim_short_name || catalog_number_namespace&.short_name
end

#dwc_coordinate_uncertainty_in_metersObject

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



213
214
215
216
217
218
219
# File 'app/models/collection_object/dwc_extensions.rb', line 213

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

#dwc_countryObject



447
448
449
450
# File 'app/models/collection_object/dwc_extensions.rb', line 447

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

#dwc_countyObject



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

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

#dwc_date_identifiedObject

ISO 8601:2004(E).



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

def dwc_date_identified
  current_taxon_determination&.date.presence
end

#dwc_dayObject



522
523
524
525
# File 'app/models/collection_object/dwc_extensions.rb', line 522

def dwc_day
  return unless collecting_event
  collecting_event.start_date_day.presence
end

#dwc_decimal_latitudeObject



466
467
468
# File 'app/models/collection_object/dwc_extensions.rb', line 466

def dwc_decimal_latitude
  georeference_attributes[:decimalLatitude]
end

#dwc_decimal_longitudeObject



470
471
472
# File 'app/models/collection_object/dwc_extensions.rb', line 470

def dwc_decimal_longitude
  georeference_attributes[:decimalLongitude]
end

#dwc_end_day_of_yearObject



532
533
534
535
# File 'app/models/collection_object/dwc_extensions.rb', line 532

def dwc_end_day_of_year
  return unless collecting_event
  collecting_event.end_day_of_year.presence
end

#dwc_event_dateObject



499
500
501
502
503
504
505
506
507
508
509
510
# File 'app/models/collection_object/dwc_extensions.rb', line 499

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



482
483
484
485
486
487
488
489
490
491
492
493
# File 'app/models/collection_object/dwc_extensions.rb', line 482

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



368
369
370
# File 'app/models/collection_object/dwc_extensions.rb', line 368

def dwc_family
  taxonomy['family']
end

#dwc_field_numberObject



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

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

#dwc_footprint_wktObject



186
187
188
# File 'app/models/collection_object/dwc_extensions.rb', line 186

def dwc_footprint_wkt
  georeference_attributes[:footprintWKT]
end

#dwc_genusObject



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

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

#dwc_geodetic_datumObject



198
199
200
# File 'app/models/collection_object/dwc_extensions.rb', line 198

def dwc_geodetic_datum
  georeference_attributes[:geodeticDatum]
end

#dwc_georeference_protocolObject



551
552
553
# File 'app/models/collection_object/dwc_extensions.rb', line 551

def dwc_georeference_protocol
  georeference_attributes[:georeferenceProtocol]
end

#dwc_georeference_remarksObject



182
183
184
# File 'app/models/collection_object/dwc_extensions.rb', line 182

def dwc_georeference_remarks
  georeference_attributes[:georeferenceRemarks]
end

#dwc_georeference_sourcesObject



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

def dwc_georeference_sources
  georeference_attributes[:georeferenceSources]
end

#dwc_georeferenced_byObject



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

def dwc_georeferenced_by
  georeference_attributes[:georeferencedBy]
end

#dwc_georeferenced_dateObject

georeferenceDate technically could look at papertrail to see when geographic_area_id appeared



208
209
210
# File 'app/models/collection_object/dwc_extensions.rb', line 208

def dwc_georeferenced_date
  georeference_attributes[:georeferencedDate]
end

#dwc_higher_classificationObject



343
344
345
346
347
348
349
# File 'app/models/collection_object/dwc_extensions.rb', line 343

def dwc_higher_classification
  v = taxonomy.values.collect{|a| a.kind_of?(Array) ? a.second : a}
  v.shift
  v.pop
  v.compact
  v.join(CollectionObject::DWC_DELIMITER)
end

#dwc_identified_byObject



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

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



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

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



443
444
445
# File 'app/models/collection_object/dwc_extensions.rb', line 443

def dwc_individual_count
  total
end

#dwc_infraspecific_epithetObject



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

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



542
543
544
# File 'app/models/collection_object/dwc_extensions.rb', line 542

def dwc_institution_code
  repository.try(:acronym)
end

#dwc_institution_idObject

we assert custody, NOT ownership



547
548
549
# File 'app/models/collection_object/dwc_extensions.rb', line 547

def dwc_institution_id
  repository_url
end

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



241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'app/models/collection_object/dwc_extensions.rb', line 241

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



351
352
353
# File 'app/models/collection_object/dwc_extensions.rb', line 351

def dwc_kingdom
  taxonomy['kingdom']
end

#dwc_life_stageObject

TODO: consider CVT attributes with Predicates linked to URIs



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

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



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

def dwc_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_maximum_depth_in_metersObject



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

def dwc_maximum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :maximumDepthInMeters)
end

#dwc_maximum_elevation_in_metersObject



298
299
300
# File 'app/models/collection_object/dwc_extensions.rb', line 298

def dwc_maximum_elevation_in_meters
  collecting_event&.maximum_elevation
end

#dwc_minimum_depth_in_metersObject



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

def dwc_minimum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :minimumDepthInMeters)
end

#dwc_minimum_elevation_in_metersObject



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

def dwc_minimum_elevation_in_meters
  collecting_event&.minimum_elevation
end

#dwc_monthObject



517
518
519
520
# File 'app/models/collection_object/dwc_extensions.rb', line 517

def dwc_month
  return unless collecting_event
  collecting_event.start_date_month.presence
end

#dwc_nomenclatural_codeObject



478
479
480
# File 'app/models/collection_object/dwc_extensions.rb', line 478

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

#dwc_occurrence_remarksObject



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

def dwc_occurrence_remarks
  notes.collect{|n| n.text}.join('|')
end

#dwc_occurrence_statusObject



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

def dwc_occurrence_status
  'present'
end

#dwc_orderObject



363
364
365
# File 'app/models/collection_object/dwc_extensions.rb', line 363

def dwc_order
  taxonomy['order']
end

#dwc_other_catalog_numbersObject



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

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_phylumObject



355
356
357
# File 'app/models/collection_object/dwc_extensions.rb', line 355

def dwc_phylum
  taxonomy['phylum']
end

#dwc_preparationsObject



537
538
539
# File 'app/models/collection_object/dwc_extensions.rb', line 537

def dwc_preparations
  preparation_type_name
end

#dwc_previous_identificationsObject



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

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.



393
394
395
396
397
398
399
400
401
402
403
404
# File 'app/models/collection_object/dwc_extensions.rb', line 393

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



407
408
409
410
411
412
413
414
415
416
417
418
# File 'app/models/collection_object/dwc_extensions.rb', line 407

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



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

def dwc_sampling_protocol
  collecting_event&.verbatim_method
end

#dwc_scientific_nameObject



382
383
384
# File 'app/models/collection_object/dwc_extensions.rb', line 382

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



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

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

#dwc_specific_epithetObject



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

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

#dwc_start_day_of_yearObject



527
528
529
530
# File 'app/models/collection_object/dwc_extensions.rb', line 527

def dwc_start_day_of_year
  return unless collecting_event
  collecting_event.start_day_of_year.presence
end

#dwc_state_provinceObject



452
453
454
455
# File 'app/models/collection_object/dwc_extensions.rb', line 452

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

#dwc_taxon_name_authorshipObject



386
387
388
# File 'app/models/collection_object/dwc_extensions.rb', line 386

def dwc_taxon_name_authorship
  current_taxon_name.try(:cached_author_year)
end

#dwc_taxon_rankObject



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

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



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

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



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

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

#dwc_verbatim_depthObject



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

def dwc_verbatim_depth
  dwc_internal_attribute_for(:collecting_event, :verbatimDepth)
end

#dwc_verbatim_elevationObject



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

def dwc_verbatim_elevation
  collecting_event&.verbatim_elevation
end

#dwc_verbatim_event_dateObject



495
496
497
# File 'app/models/collection_object/dwc_extensions.rb', line 495

def dwc_verbatim_event_date
  collecting_event&.verbatim_date
end

#dwc_verbatim_habitatObject



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

def dwc_verbatim_habitat
  collecting_event&.verbatim_habitat
end

#dwc_verbatim_latitudeObject



221
222
223
# File 'app/models/collection_object/dwc_extensions.rb', line 221

def dwc_verbatim_latitude
  collecting_event&.verbatim_latitude
end

#dwc_verbatim_localityObject



474
475
476
# File 'app/models/collection_object/dwc_extensions.rb', line 474

def dwc_verbatim_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_verbatim_longitudeObject



225
226
227
# File 'app/models/collection_object/dwc_extensions.rb', line 225

def dwc_verbatim_longitude
  collecting_event&.verbatim_longitude
end

#dwc_verbatim_srsObject



202
203
204
# File 'app/models/collection_object/dwc_extensions.rb', line 202

def dwc_verbatim_srs
  georeference_attributes[:dwcVerbatimSrs]
end

#dwc_water_bodyObject



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

def dwc_water_body
  dwc_internal_attribute_for(:collecting_event, :waterBody)
end

#dwc_yearObject



512
513
514
515
# File 'app/models/collection_object/dwc_extensions.rb', line 512

def dwc_year
  return unless collecting_event
  collecting_event.start_date_year.presence
end

#is_fossil?Boolean

Returns:

  • (Boolean)


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

def is_fossil?
  biocuration_classes.where(uri: DWC_FOSSIL_URI).any?
end

#set_georeference_attributesHash

Returns:

  • (Hash)


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

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