Last active
December 9, 2016 19:19
-
-
Save remomueller/4197c99376ea8e41fb059fc9d35fa7c0 to your computer and use it in GitHub Desktop.
Parse XML Annotation Files and retrieve time asleep and number of obstructive apnea events.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
# gem install xml-simple colorize --no-document | |
# ruby annotation_testing.rb | |
require 'rubygems' | |
require 'colorize' | |
require 'json' | |
require 'xmlsimple' | |
# Take the XML files in this folder `/annotation-testing` and answer two | |
# questions: | |
# 1) How many epochs/minutes was the subject asleep? | |
# 2) How many obstructive apnea events were marked on the recording? | |
# Asleep is defined as SleepStage = 1,2,3,4,5 | |
def extract(hash, key, convert: nil) | |
value = hash[key] ? hash[key][0] : nil | |
convert && value ? value.send(convert) : value | |
end | |
Dir.glob('**/*.xml', File::FNM_CASEFOLD).each do |xml_path| | |
xml = XmlSimple.xml_in(xml_path) | |
epoch_length = xml['EpochLength'][0].to_i | |
sleep_stages = xml['SleepStages'][0]['SleepStage'] | |
# awake_stages = sleep_stages.select { |stage| %w(0).include?(stage) } | |
asleep_stages = sleep_stages.select { |stage| %w(1 2 3 4 5).include?(stage) } | |
scored_events = xml['ScoredEvents'][0]['ScoredEvent'].collect do |hash| | |
{ | |
name: extract(hash, 'Name'), | |
lowest_spo2: extract(hash, 'LowestSpO2', convert: :to_f), | |
desaturation: extract(hash, 'Desaturation', convert: :to_f), | |
start: extract(hash, 'Start', convert: :to_f), | |
duration: extract(hash, 'Duration', convert: :to_f), | |
input: extract(hash, 'Input') | |
} | |
end | |
obstructive_apnea_events = scored_events.select do |event| | |
event[:name] == 'Obstructive Apnea' | |
end | |
message = \ | |
"\n#{xml_path}\n"\ | |
"The subject was asleep for #{asleep_stages.count} of total "\ | |
"#{sleep_stages.count} sleep stages.\nThis comes to "\ | |
"#{(asleep_stages.count * epoch_length / 60.0).to_s.colorize(:green)} "\ | |
"minutes of #{sleep_stages.count * epoch_length / 60.0} minutes total.\n"\ | |
"#{obstructive_apnea_events.count.to_s.colorize(:green)} obstructive apnea"\ | |
" were scored.\n\n" | |
puts message | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment