Module: FieldOccurrence::DwcExtensions

Extended by:
ActiveSupport::Concern
Included in:
FieldOccurrence
Defined in:
app/models/field_occurrence/dwc_extensions.rb

Instance Method Summary collapse

Instance Method Details

TODO: likeley a helper



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

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



197
198
199
# File 'app/models/field_occurrence/dwc_extensions.rb', line 197

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

#dwc_associated_taxaObject



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

def dwc_associated_taxa
  dwc_internal_attribute_for(:collection_object, :associatedTaxa)
end

#dwc_casteObject



329
330
331
332
# File 'app/models/field_occurrence/dwc_extensions.rb', line 329

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

#dwc_catalog_numberObject



502
503
504
# File 'app/models/field_occurrence/dwc_extensions.rb', line 502

def dwc_catalog_number
  catalog_number_cached # via delegation
end

#dwc_classObject



404
405
406
# File 'app/models/field_occurrence/dwc_extensions.rb', line 404

def dwc_class
  taxonomy['class']
end

#dwc_collection_codeObject



498
499
500
# File 'app/models/field_occurrence/dwc_extensions.rb', line 498

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



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

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

#dwc_countryObject



511
512
513
514
# File 'app/models/field_occurrence/dwc_extensions.rb', line 511

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

#dwc_countyObject



521
522
523
524
# File 'app/models/field_occurrence/dwc_extensions.rb', line 521

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

#dwc_date_identifiedObject

ISO 8601:2004(E).



384
385
386
# File 'app/models/field_occurrence/dwc_extensions.rb', line 384

def dwc_date_identified
  current_taxon_determination&.date.presence
end

#dwc_dayObject



586
587
588
589
# File 'app/models/field_occurrence/dwc_extensions.rb', line 586

def dwc_day
  return unless collecting_event
  collecting_event.start_date_day.presence
end

#dwc_decimal_latitudeObject



530
531
532
# File 'app/models/field_occurrence/dwc_extensions.rb', line 530

def dwc_decimal_latitude
  georeference_attributes[:decimalLatitude]
end

#dwc_decimal_longitudeObject



534
535
536
# File 'app/models/field_occurrence/dwc_extensions.rb', line 534

def dwc_decimal_longitude
  georeference_attributes[:decimalLongitude]
end

#dwc_end_day_of_yearObject



596
597
598
599
# File 'app/models/field_occurrence/dwc_extensions.rb', line 596

def dwc_end_day_of_year
  return unless collecting_event
  collecting_event.end_day_of_year.presence
end

#dwc_event_dateObject



563
564
565
566
567
568
569
570
571
572
573
574
# File 'app/models/field_occurrence/dwc_extensions.rb', line 563

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



192
193
194
# File 'app/models/field_occurrence/dwc_extensions.rb', line 192

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

#dwc_event_timeObject



546
547
548
549
550
551
552
553
554
555
556
557
# File 'app/models/field_occurrence/dwc_extensions.rb', line 546

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



418
419
420
# File 'app/models/field_occurrence/dwc_extensions.rb', line 418

def dwc_family
  taxonomy['family']
end

#dwc_field_numberObject



356
357
358
359
# File 'app/models/field_occurrence/dwc_extensions.rb', line 356

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

#dwc_footprint_wktObject



226
227
228
# File 'app/models/field_occurrence/dwc_extensions.rb', line 226

def dwc_footprint_wkt
  georeference_attributes[:footprintWKT]
end

#dwc_genusObject



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

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

#dwc_geodetic_datumObject



238
239
240
# File 'app/models/field_occurrence/dwc_extensions.rb', line 238

def dwc_geodetic_datum
  georeference_attributes[:geodeticDatum]
end

#dwc_georeference_protocolObject



615
616
617
# File 'app/models/field_occurrence/dwc_extensions.rb', line 615

def dwc_georeference_protocol
  georeference_attributes[:georeferenceProtocol]
end

#dwc_georeference_remarksObject



222
223
224
# File 'app/models/field_occurrence/dwc_extensions.rb', line 222

def dwc_georeference_remarks
  georeference_attributes[:georeferenceRemarks]
end

#dwc_georeference_sourcesObject



218
219
220
# File 'app/models/field_occurrence/dwc_extensions.rb', line 218

def dwc_georeference_sources
  georeference_attributes[:georeferenceSources]
end

#dwc_georeferenced_byObject



230
231
232
# File 'app/models/field_occurrence/dwc_extensions.rb', line 230

def dwc_georeferenced_by
  georeference_attributes[:georeferencedBy]
end

#dwc_georeferenced_dateObject

georeferenceDate technically could look at papertrail to see when geographic_area_id appeared



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

def dwc_georeferenced_date
  georeference_attributes[:georeferencedDate]
end

#dwc_higher_classificationObject



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

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

#dwc_identification_remarksObject



188
189
190
# File 'app/models/field_occurrence/dwc_extensions.rb', line 188

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

#dwc_identified_byObject



484
485
486
487
# File 'app/models/field_occurrence/dwc_extensions.rb', line 484

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(FieldOccurrence::DWC_DELIMITER).presence
end

#dwc_identified_by_idObject



489
490
491
492
# File 'app/models/field_occurrence/dwc_extensions.rb', line 489

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(FieldOccurrence::DWC_DELIMITER).presence
end

#dwc_individual_countObject

TODO: handle ranged lots



507
508
509
# File 'app/models/field_occurrence/dwc_extensions.rb', line 507

def dwc_individual_count
  total
end

#dwc_infraspecific_epithetObject



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

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



606
607
608
# File 'app/models/field_occurrence/dwc_extensions.rb', line 606

def dwc_institution_code
  repository.try(:acronym)
end

#dwc_institution_idObject

we assert custody, NOT ownership



611
612
613
# File 'app/models/field_occurrence/dwc_extensions.rb', line 611

def dwc_institution_id
  repository_url
end

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



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

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



396
397
398
# File 'app/models/field_occurrence/dwc_extensions.rb', line 396

def dwc_kingdom
  taxonomy['kingdom']
end

#dwc_life_stageObject

TODO: consider CVT attributes with Predicates linked to URIs



318
319
320
321
# File 'app/models/field_occurrence/dwc_extensions.rb', line 318

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



526
527
528
# File 'app/models/field_occurrence/dwc_extensions.rb', line 526

def dwc_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_maximum_depth_in_metersObject



309
310
311
# File 'app/models/field_occurrence/dwc_extensions.rb', line 309

def dwc_maximum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :maximumDepthInMeters)
end

#dwc_maximum_elevation_in_metersObject



343
344
345
# File 'app/models/field_occurrence/dwc_extensions.rb', line 343

def dwc_maximum_elevation_in_meters
  collecting_event&.maximum_elevation
end

#dwc_minimum_depth_in_metersObject



305
306
307
# File 'app/models/field_occurrence/dwc_extensions.rb', line 305

def dwc_minimum_depth_in_meters
  dwc_internal_attribute_for(:collecting_event, :minimumDepthInMeters)
end

#dwc_minimum_elevation_in_metersObject



347
348
349
# File 'app/models/field_occurrence/dwc_extensions.rb', line 347

def dwc_minimum_elevation_in_meters
  collecting_event&.minimum_elevation
end

#dwc_monthObject



581
582
583
584
# File 'app/models/field_occurrence/dwc_extensions.rb', line 581

def dwc_month
  return unless collecting_event
  collecting_event.start_date_month.presence
end

#dwc_nomenclatural_codeObject



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

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

#dwc_occurrence_remarksObject



183
184
185
# File 'app/models/field_occurrence/dwc_extensions.rb', line 183

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

#dwc_occurrence_statusObject



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

def dwc_occurrence_status
  'present'
end

#dwc_orderObject



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

def dwc_order
  taxonomy['order']
end

#dwc_other_catalog_numbersObject



269
270
271
272
273
# File 'app/models/field_occurrence/dwc_extensions.rb', line 269

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

#dwc_phylumObject



400
401
402
# File 'app/models/field_occurrence/dwc_extensions.rb', line 400

def dwc_phylum
  taxonomy['phylum']
end

#dwc_preparationsObject



601
602
603
# File 'app/models/field_occurrence/dwc_extensions.rb', line 601

def dwc_preparations
  preparation_type_name
end

#dwc_previous_identificationsObject



275
276
277
278
279
# File 'app/models/field_occurrence/dwc_extensions.rb', line 275

def dwc_previous_identifications
  a = taxon_determinations.order(:position).to_a
  a.shift
  a.collect{|d| ApplicationController.helpers.label_for_taxon_determination(d)}.join(FieldOccurrence::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.



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

def dwc_recorded_by
  v = nil
  if collecting_event
    v = collecting_event.collectors
      .order('roles.position')
      .map(&:name)
      .join(FieldOccurrence::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



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

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

#dwc_sampling_protocolObject

TODO: Reconcile with Protocol (capital P) assignments



352
353
354
# File 'app/models/field_occurrence/dwc_extensions.rb', line 352

def dwc_sampling_protocol
  collecting_event&.verbatim_method
end

#dwc_scientific_nameObject



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

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



324
325
326
327
# File 'app/models/field_occurrence/dwc_extensions.rb', line 324

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

#dwc_specific_epithetObject



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

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

#dwc_start_day_of_yearObject



591
592
593
594
# File 'app/models/field_occurrence/dwc_extensions.rb', line 591

def dwc_start_day_of_year
  return unless collecting_event
  collecting_event.start_day_of_year.presence
end

#dwc_state_provinceObject



516
517
518
519
# File 'app/models/field_occurrence/dwc_extensions.rb', line 516

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

#dwc_subfamilyObject



423
424
425
# File 'app/models/field_occurrence/dwc_extensions.rb', line 423

def dwc_subfamily
  taxonomy['subfamily']
end

#dwc_subtribeObject



433
434
435
# File 'app/models/field_occurrence/dwc_extensions.rb', line 433

def dwc_subtribe
  taxonomy['subtribe']
end

#dwc_superfamilyObject



413
414
415
# File 'app/models/field_occurrence/dwc_extensions.rb', line 413

def dwc_superfamily
  taxonomy['superfamily']
end

#dwc_taxon_name_authorshipObject



451
452
453
# File 'app/models/field_occurrence/dwc_extensions.rb', line 451

def dwc_taxon_name_authorship
  current_taxon_name.try(:cached_author_year)
end

#dwc_taxon_rankObject



372
373
374
# File 'app/models/field_occurrence/dwc_extensions.rb', line 372

def dwc_taxon_rank
  current_taxon_name&.rank
end

#dwc_tribeObject



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

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



377
378
379
380
381
# File 'app/models/field_occurrence/dwc_extensions.rb', line 377

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

#dwc_verbatim_coordinatesObject



334
335
336
337
# File 'app/models/field_occurrence/dwc_extensions.rb', line 334

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

#dwc_verbatim_depthObject



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

def dwc_verbatim_depth
  dwc_internal_attribute_for(:collecting_event, :verbatimDepth)
end

#dwc_verbatim_elevationObject



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

def dwc_verbatim_elevation
  collecting_event&.verbatim_elevation
end

#dwc_verbatim_event_dateObject



559
560
561
# File 'app/models/field_occurrence/dwc_extensions.rb', line 559

def dwc_verbatim_event_date
  collecting_event&.verbatim_date
end

#dwc_verbatim_habitatObject



361
362
363
# File 'app/models/field_occurrence/dwc_extensions.rb', line 361

def dwc_verbatim_habitat
  collecting_event&.verbatim_habitat
end

#dwc_verbatim_labelObject

use buffered if any if not check CE verbatim_label



172
173
174
175
176
# File 'app/models/field_occurrence/dwc_extensions.rb', line 172

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



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

def dwc_verbatim_latitude
  collecting_event&.verbatim_latitude
end

#dwc_verbatim_localityObject



538
539
540
# File 'app/models/field_occurrence/dwc_extensions.rb', line 538

def dwc_verbatim_locality
  collecting_event.try(:verbatim_locality)
end

#dwc_verbatim_longitudeObject



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

def dwc_verbatim_longitude
  collecting_event&.verbatim_longitude
end

#dwc_verbatim_srsObject



242
243
244
# File 'app/models/field_occurrence/dwc_extensions.rb', line 242

def dwc_verbatim_srs
  georeference_attributes[:dwcVerbatimSrs]
end

#dwc_water_bodyObject



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

def dwc_water_body
  dwc_internal_attribute_for(:collecting_event, :waterBody)
end

#dwc_yearObject



576
577
578
579
# File 'app/models/field_occurrence/dwc_extensions.rb', line 576

def dwc_year
  return unless collecting_event
  collecting_event.start_date_year.presence
end

#is_fossil?Boolean

Returns:

  • (Boolean)


166
167
168
# File 'app/models/field_occurrence/dwc_extensions.rb', line 166

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/field_occurrence/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