Skip to content

Commit

Permalink
Enhanced Event class fields parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
LocoDelAssembly committed Sep 16, 2020
1 parent 8ac9290 commit 1b8c7fd
Showing 1 changed file with 123 additions and 11 deletions.
134 changes: 123 additions & 11 deletions app/models/dataset_record/darwin_core/occurrence.rb
Expand Up @@ -52,26 +52,19 @@ def import
})


### Create collecting event
#end_date = Date.ordinal(get_field_value("year").to_i, get_field_value("endDayOfYear").to_i)
### Parse Event class fields
attributes = parse_event_class

#TODO: If all attributes are equal assume it is the same event and share it with other specimens?

This comment has been minimized.

Copy link
@mjy

mjy Sep 16, 2020

Member

Yes. This was instantly noticed by users, the very first thing. We will have to have some careful consideration as t how to do this, it's non-trivial.

Pre-indexing identity might speed loads as well. Not sure.

CollectingEvent.create!({
verbatim_date: get_field_value("verbatimEventDate"),
start_date_year: get_field_value("year"),
start_date_month: get_field_value("month"),
start_date_day: get_field_value("day"),
#end_date_year: end_date.year,
#end_date_month: end_date.month,
#end_date_day: end_date.day,
collection_objects: [specimen],
with_verbatim_data_georeference: true,
verbatim_latitude: get_field_value("decimalLatitude"),
verbatim_longitude: get_field_value("decimalLongitude"),
verbatim_datum: get_field_value("geodeticDatum"),
verbatim_locality: get_field_value("locality"),
no_dwc_occurrence: true
})
}.merge!(attributes[:collecting_event]))

self.metadata["imported_objects"] = { collection_object: { id: specimen.id } }
self.status = "Imported"
Expand Down Expand Up @@ -110,10 +103,26 @@ def get_fields_mapping
end

def get_field_value(field_name)
index = get_fields_mapping[field_name]
index = get_fields_mapping[field_name.to_s]
data_fields[index]&.dig("value") if index
end

def get_integer_field_value(field_name)
value = get_field_value(field_name)

unless value.blank?
begin
value = Integer(value)
rescue
raise DarwinCore::InvalidData.new({ field_name => ["'#{value} is not a valid integer value"] })
end
else
value = nil
end

value
end

def parse_identifiedBy
DwcAgent.parse(get_field_value("identifiedBy")).map! do |name|
{
Expand All @@ -123,7 +132,110 @@ def parse_identifiedBy
prefix: name.title || name.appellation
}
end
end

def set_hash_val(hsh, key, value)
hsh[key] = value unless value.nil?
end

def parse_event_class
collecting_event = { }

# eventID: [Not mapped]

# parentEventID: [Not mapped]

# fieldNumber: verbatim_trip_identifier
set_hash_val(collecting_event, :verbatim_trip_identifier, get_field_value(:fieldNumber))

eventDate = get_field_value(:eventDate)

begin
start_date = DateTime.iso8601(eventDate) if eventDate
rescue Date::Error
raise DarwinCore::InvalidData.new({ "eventDate": ["Invalid date. Please make sure it conforms to ISO 8601"] })
end

year = get_integer_field_value(:year)
month = get_integer_field_value(:month)
day = get_integer_field_value(:day)
startDayOfYear = get_integer_field_value(:startDayOfYear)

raise DarwinCore::InvalidData.new({ "eventDate": ["Conflicting values. Please check year, month, and day match eventDate"] }) if start_date &&
(year && start_date.year != year || month && start_date.month != month || day && start_date.day != day)

year ||= start_date&.year
month ||= start_date&.month
day ||= start_date&.day

if startDayOfYear
raise DarwinCore::InvalidData.new({ "startDayOfYear": ["Missing year value"] }) if year.nil? || eventDate.nil?

begin
ordinal = Date.ordinal(year, startDayOfYear)
rescue Date::Error
raise DarwinCore::InvalidData.new({ "startDayOfYear": ["Out of range. Please also check year field"] })
end

if month && ordinal.month != month || day && ordinal.day != day
raise DarwinCore::InvalidData.new({ "startDayOfYear": ["Month and/or day of the event date do not match"] })
end

month ||= ordinal.month
day ||= ordinal.day
end

# eventDate | (year+month+day) | (year+startDayOfYear): start_date_*
set_hash_val(collecting_event, :start_date_year, year)
set_hash_val(collecting_event, :start_date_month, month)
set_hash_val(collecting_event, :start_date_day, day)

# eventTime: time_start_*
/(?<hour>\d+)(:(?<minute>\d+))?(:(?<second>\d+))?/ =~ get_field_value(:eventTime)
set_hash_val(collecting_event, :time_start_hour, hour)
set_hash_val(collecting_event, :time_start_minute, minute)
set_hash_val(collecting_event, :time_start_second, second)

endDayOfYear = get_integer_field_value(:endDayOfYear)

if endDayOfYear
raise DarwinCore::InvalidData.new({ "endDayOfYear": ["Missing year value"] }) if year.nil? || eventDate.nil?

begin
ordinal = Date.ordinal(year, endDayOfYear)
rescue Date::Error
raise DarwinCore::InvalidData.new({ "endDayOfYear": ["Out of range. Please also check year field"] })
end

month = ordinal.month
day = ordinal.day
end

# endDayOfYear: end_date_* ## TODO: Might need to support date ranges for eventDate as this field does not make possible to end next year
set_hash_val(collecting_event, :end_date_year, year)
set_hash_val(collecting_event, :end_date_month, month)
set_hash_val(collecting_event, :end_date_day, day)

# verbatimEventDate: verbatim_date
set_hash_val(collecting_event, :verbatimEventDate, get_field_value(:verbatim_date))

# habitat: verbatim_habitat
set_hash_val(collecting_event, :verbatim_habitat, get_field_value(:habitat))

# samplingProtocol: verbatim_method
set_hash_val(collecting_event, :verbatim_method, get_field_value(:samplingProtocol))

# sampleSizeValue: [Not mapped]

# sampleSizeUnit: [Not mapped]

# samplingEffort: [Not mapped]

# fieldNotes: field_notes
set_hash_val(collecting_event, :field_notes, get_field_value(:fieldNotes))

# eventRemarks: Maybe field_notes (concatenated with fieldNotes)

{ collecting_event: collecting_event }
end
end

0 comments on commit 1b8c7fd

Please sign in to comment.