Module: CollectionObject::DwcExtensions

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

Defined Under Namespace

Modules: TaxonworksExtensions

Instance Method Summary collapse

Instance Method Details

TODO: likeley a helper



208
209
210
211
212
213
214
215
216
217
# File 'app/models/collection_object/dwc_extensions.rb', line 208

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



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

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

#dwc_associated_taxaObject



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

def dwc_associated_taxa
  dwc_internal_attribute_for(:collection_object, :associatedTaxa)
end

#dwc_casteObject



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

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

#dwc_catalog_numberObject



509
510
511
# File 'app/models/collection_object/dwc_extensions.rb', line 509

def dwc_catalog_number
  catalog_number_cached # via delegation
end

#dwc_classObject



405
406
407
# File 'app/models/collection_object/dwc_extensions.rb', line 405

def dwc_class
  taxonomy['class']
end

#dwc_collection_codeObject



505
506
507
# File 'app/models/collection_object/dwc_extensions.rb', line 505

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



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

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

#dwc_countryObject



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

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

#dwc_countyObject



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

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

#dwc_date_identifiedObject

ISO 8601:2004(E).



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

def dwc_date_identified
  current_taxon_determination&.date.presence
end

#dwc_dayObject



593
594
595
596
# File 'app/models/collection_object/dwc_extensions.rb', line 593

def dwc_day
  return unless collecting_event
  collecting_event.start_date_day.presence
end

#dwc_decimal_latitudeObject



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

def dwc_decimal_latitude
  georeference_attributes[:decimalLatitude]
end

#dwc_decimal_longitudeObject



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

def dwc_decimal_longitude
  georeference_attributes[:decimalLongitude]
end

#dwc_end_day_of_yearObject



603
604
605
606
# File 'app/models/collection_object/dwc_extensions.rb', line 603

def dwc_end_day_of_year
  return unless collecting_event
  collecting_event.end_day_of_year.presence
end

#dwc_event_dateObject



570
571
572
573
574
575
576
577
578
579
580
581
# File 'app/models/collection_object/dwc_extensions.rb', line 570

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_remarksObject



193
194
195
# File 'app/models/collection_object/dwc_extensions.rb', line 193

def dwc_event_remarks
  collecting_event&.notes&.collect {|n| n.text}&.join(CollectionObject::DWC_DELIMITER)
end

#dwc_event_timeObject



553
554
555
556
557
558
559
560
561
562
563
564
# File 'app/models/collection_object/dwc_extensions.rb', line 553

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



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

def dwc_family
  taxonomy['family']
end

#dwc_field_numberObject



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

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

#dwc_footprint_wktObject



227
228
229
# File 'app/models/collection_object/dwc_extensions.rb', line 227

def dwc_footprint_wkt
  georeference_attributes[:footprintWKT]
end

#dwc_genusObject



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

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

#dwc_geodetic_datumObject



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

def dwc_geodetic_datum
  georeference_attributes[:geodeticDatum]
end

#dwc_georeference_protocolObject



612
613
614
# File 'app/models/collection_object/dwc_extensions.rb', line 612

def dwc_georeference_protocol
  georeference_attributes[:georeferenceProtocol]
end

#dwc_georeference_remarksObject



223
224
225
# File 'app/models/collection_object/dwc_extensions.rb', line 223

def dwc_georeference_remarks
  georeference_attributes[:georeferenceRemarks]
end

#dwc_georeference_sourcesObject



219
220
221
# File 'app/models/collection_object/dwc_extensions.rb', line 219

def dwc_georeference_sources
  georeference_attributes[:georeferenceSources]
end

#dwc_georeferenced_byObject



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

def dwc_georeferenced_by
  georeference_attributes[:georeferencedBy]
end

#dwc_georeferenced_dateObject

georeferenceDate technically could look at papertrail to see when geographic_area_id appeared



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

def dwc_georeferenced_date
  georeference_attributes[:georeferencedDate]
end

#dwc_higher_classificationObject



389
390
391
392
393
394
395
# File 'app/models/collection_object/dwc_extensions.rb', line 389

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_identification_remarksObject



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

def dwc_identification_remarks
  current_taxon_determination&.notes&.collect { |n| n.text }&.join(CollectionObject::DWC_DELIMITER)
end

#dwc_identified_byObject



485
486
487
488
# File 'app/models/collection_object/dwc_extensions.rb', line 485

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(&:name)&.join(CollectionObject::DWC_DELIMITER).presence
end

#dwc_identified_by_idObject



490
491
492
493
# File 'app/models/collection_object/dwc_extensions.rb', line 490

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



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

def dwc_individual_count
  total
end

#dwc_infraspecific_epithetObject



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

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



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

def dwc_institution_code
  repository_acronym
end

#dwc_institution_idObject

we assert custody, NOT ownership



501
502
503
# File 'app/models/collection_object/dwc_extensions.rb', line 501

def dwc_institution_id
  repository_url
end

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



282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'app/models/collection_object/dwc_extensions.rb', line 282

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



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

def dwc_kingdom
  taxonomy['kingdom']
end

#dwc_life_stageObject

TODO: consider CVT attributes with Predicates linked to URIs



319
320
321
322
# File 'app/models/collection_object/dwc_extensions.rb', line 319

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



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

def dwc_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_maximum_depth_in_metersObject



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

def dwc_maximum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :maximumDepthInMeters)
end

#dwc_maximum_elevation_in_metersObject



344
345
346
# File 'app/models/collection_object/dwc_extensions.rb', line 344

def dwc_maximum_elevation_in_meters
  collecting_event&.maximum_elevation
end

#dwc_minimum_depth_in_metersObject



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

def dwc_minimum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :minimumDepthInMeters)
end

#dwc_minimum_elevation_in_metersObject



348
349
350
# File 'app/models/collection_object/dwc_extensions.rb', line 348

def dwc_minimum_elevation_in_meters
  collecting_event&.minimum_elevation
end

#dwc_monthObject



588
589
590
591
# File 'app/models/collection_object/dwc_extensions.rb', line 588

def dwc_month
  return unless collecting_event
  collecting_event.start_date_month.presence
end

#dwc_nomenclatural_codeObject



549
550
551
# File 'app/models/collection_object/dwc_extensions.rb', line 549

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

#dwc_occurrence_remarksObject



184
185
186
# File 'app/models/collection_object/dwc_extensions.rb', line 184

def dwc_occurrence_remarks
  notes.collect{|n| n.text}&.join(CollectionObject::DWC_DELIMITER)
end

#dwc_occurrence_statusObject



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

def dwc_occurrence_status
  'present'
end

#dwc_orderObject



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

def dwc_order
  taxonomy['order']
end

#dwc_other_catalog_numbersObject



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

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



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

def dwc_phylum
  taxonomy['phylum']
end

#dwc_preparationsObject



608
609
610
# File 'app/models/collection_object/dwc_extensions.rb', line 608

def dwc_preparations
  preparation_type_name
end

#dwc_previous_identificationsObject



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

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 aspects of the data.



459
460
461
462
463
464
465
466
467
468
469
470
# File 'app/models/collection_object/dwc_extensions.rb', line 459

def dwc_recorded_by
  v = nil
  if collecting_event
    v = collecting_event.collectors
      .order('roles.position')
      .map(&:name)
      .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 TODO: Expand to any GlobalIdentifier



474
475
476
477
478
479
480
481
482
483
# File 'app/models/collection_object/dwc_extensions.rb', line 474

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



353
354
355
# File 'app/models/collection_object/dwc_extensions.rb', line 353

def dwc_sampling_protocol
  collecting_event&.verbatim_method
end

#dwc_scientific_nameObject



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

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



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

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

#dwc_specific_epithetObject



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

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

#dwc_start_day_of_yearObject



598
599
600
601
# File 'app/models/collection_object/dwc_extensions.rb', line 598

def dwc_start_day_of_year
  return unless collecting_event
  collecting_event.start_day_of_year.presence
end

#dwc_state_provinceObject



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

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

#dwc_subfamilyObject



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

def dwc_subfamily
  taxonomy['subfamily']
end

#dwc_subtribeObject



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

def dwc_subtribe
  taxonomy['subtribe']
end

#dwc_superfamilyObject



414
415
416
# File 'app/models/collection_object/dwc_extensions.rb', line 414

def dwc_superfamily
  taxonomy['superfamily']
end

#dwc_taxon_name_authorshipObject



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

def dwc_taxon_name_authorship
  current_taxon_name.try(:cached_author_year)
end

#dwc_taxon_rankObject



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

def dwc_taxon_rank
  current_taxon_name&.rank
end

#dwc_tribeObject



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

def dwc_tribe
  taxonomy['tribe']
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



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

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



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

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

#dwc_verbatim_depthObject



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

def dwc_verbatim_depth
  dwc_internal_attribute_for(:collecting_event, :verbatimDepth)
end

#dwc_verbatim_elevationObject



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

def dwc_verbatim_elevation
  collecting_event&.verbatim_elevation
end

#dwc_verbatim_event_dateObject



566
567
568
# File 'app/models/collection_object/dwc_extensions.rb', line 566

def dwc_verbatim_event_date
  collecting_event&.verbatim_date
end

#dwc_verbatim_habitatObject



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

def dwc_verbatim_habitat
  collecting_event&.verbatim_habitat
end

#dwc_verbatim_labelObject

use buffered if any if not check CE verbatim_label



173
174
175
176
177
# File 'app/models/collection_object/dwc_extensions.rb', line 173

def dwc_verbatim_label
  b = [buffered_collecting_event, buffered_determinations, buffered_other_labels].compact
  return  b.join("\n\n") if b.present?
  collecting_event&.verbatim_label.presence
end

#dwc_verbatim_latitudeObject



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

def dwc_verbatim_latitude
  collecting_event&.verbatim_latitude
end

#dwc_verbatim_localityObject



545
546
547
# File 'app/models/collection_object/dwc_extensions.rb', line 545

def dwc_verbatim_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_verbatim_longitudeObject



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

def dwc_verbatim_longitude
  collecting_event&.verbatim_longitude
end

#dwc_verbatim_srsObject



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

def dwc_verbatim_srs
  georeference_attributes[:dwcVerbatimSrs]
end

#dwc_water_bodyObject



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

def dwc_water_body
  dwc_internal_attribute_for(:collecting_event, :waterBody)
end

#dwc_yearObject



583
584
585
586
# File 'app/models/collection_object/dwc_extensions.rb', line 583

def dwc_year
  return unless collecting_event
  collecting_event.start_date_year.presence
end

#is_fossil?Boolean

Returns:

  • (Boolean)


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

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

#set_georeference_attributesHash

Returns:

  • (Hash)


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

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