health-data-standards 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/lib/health-data-standards.rb +4 -1
- data/lib/health-data-standards/export/html.rb +2 -2
- data/lib/health-data-standards/export/view_helper.rb +4 -4
- data/lib/health-data-standards/import/c32/encounter_importer.rb +1 -0
- data/lib/health-data-standards/import/c32/section_importer.rb +1 -1
- data/lib/health-data-standards/import/green_c32/encounter_importer.rb +5 -8
- data/lib/health-data-standards/import/green_c32/section_importer.rb +16 -0
- data/lib/health-data-standards/models/coded_result_value.rb +1 -0
- data/lib/health-data-standards/models/facility.rb +3 -0
- data/lib/health-data-standards/models/insurance_provider.rb +1 -0
- data/lib/health-data-standards/models/medical_equipment.rb +4 -1
- data/lib/health-data-standards/models/procedure.rb +5 -1
- data/lib/health-data-standards/models/provider.rb +0 -1
- data/lib/health-data-standards/models/record.rb +14 -2
- data/lib/health-data-standards/models/svs/concept.rb +16 -0
- data/lib/health-data-standards/models/svs/value_set.rb +30 -0
- data/lib/health-data-standards/util/code_system_helper.rb +3 -1
- data/lib/health-data-standards/util/hqmf_template_helper.rb +28 -0
- data/lib/health-data-standards/util/vs_api.rb +43 -0
- metadata +23 -3
- data/lib/health-data-standards/util/qrda_template_helper.rb +0 -20
data/Gemfile
CHANGED
@@ -12,7 +12,8 @@ require_relative 'health-data-standards/ext/string'
|
|
12
12
|
|
13
13
|
require_relative 'health-data-standards/util/hl7_helper'
|
14
14
|
require_relative 'health-data-standards/util/code_system_helper'
|
15
|
-
require_relative 'health-data-standards/util/
|
15
|
+
require_relative 'health-data-standards/util/hqmf_template_helper'
|
16
|
+
require_relative 'health-data-standards/util/vs_api'
|
16
17
|
|
17
18
|
require_relative 'health-data-standards/export/template_helper'
|
18
19
|
require_relative 'health-data-standards/export/view_helper'
|
@@ -59,6 +60,8 @@ require_relative 'health-data-standards/models/person'
|
|
59
60
|
require_relative 'health-data-standards/models/organization'
|
60
61
|
require_relative 'health-data-standards/models/address'
|
61
62
|
require_relative 'health-data-standards/models/telecom'
|
63
|
+
require_relative 'health-data-standards/models/svs/value_set'
|
64
|
+
require_relative 'health-data-standards/models/svs/concept'
|
62
65
|
require_relative 'health-data-standards/models/facility'
|
63
66
|
require_relative 'health-data-standards/models/metadata/base'
|
64
67
|
require_relative 'health-data-standards/models/metadata/author'
|
@@ -3,10 +3,10 @@ module HealthDataStandards
|
|
3
3
|
module HTML
|
4
4
|
include TemplateHelper
|
5
5
|
|
6
|
-
def export(patient)
|
6
|
+
def export(patient, concept_map=nil)
|
7
7
|
self.template_format = "html"
|
8
8
|
self.template_subdir = "html"
|
9
|
-
render(:template => 'show', :locals => {:patient => patient})
|
9
|
+
render(:template => 'show', :locals => {:patient => patient, :concept_map=>concept_map})
|
10
10
|
end
|
11
11
|
|
12
12
|
extend self
|
@@ -84,16 +84,16 @@ module HealthDataStandards
|
|
84
84
|
return ["true","false"].include? (str || "").downcase
|
85
85
|
end
|
86
86
|
|
87
|
-
def
|
87
|
+
def decode_hqmf_section(section, oid)
|
88
88
|
if oid
|
89
|
-
HealthDataStandards::Util::
|
89
|
+
HealthDataStandards::Util::HQMFTemplateHelper.definition_for_template_id(oid)['definition'].pluralize.to_sym
|
90
90
|
else
|
91
91
|
section
|
92
92
|
end
|
93
93
|
end
|
94
|
-
def
|
94
|
+
def decode_hqmf_status(status, oid)
|
95
95
|
if oid
|
96
|
-
HealthDataStandards::Util::
|
96
|
+
HealthDataStandards::Util::HQMFTemplateHelper.definition_for_template_id(oid)['status']
|
97
97
|
else
|
98
98
|
status
|
99
99
|
end
|
@@ -60,6 +60,7 @@ module HealthDataStandards
|
|
60
60
|
facility.addresses = participant_element.xpath("./cda:addr").try(:map) {|ae| import_address(ae)}
|
61
61
|
facility.telecoms = participant_element.xpath("./cda:telecom").try(:map) {|te| import_telecom(te)}
|
62
62
|
facility.code = extract_code(participant_element, './cda:code')
|
63
|
+
extract_dates(participant_element.parent, facility, "time")
|
63
64
|
encounter.facility = facility
|
64
65
|
end
|
65
66
|
end
|
@@ -108,7 +108,7 @@ module HealthDataStandards
|
|
108
108
|
end
|
109
109
|
|
110
110
|
def extract_dates(parent_element, entry, element_name="effectiveTime")
|
111
|
-
if parent_element.at_xpath("cda:#{element_name}")
|
111
|
+
if parent_element.at_xpath("cda:#{element_name}/@value")
|
112
112
|
entry.time = HL7Helper.timestamp_to_integer(parent_element.at_xpath("cda:#{element_name}")['value'])
|
113
113
|
end
|
114
114
|
if parent_element.at_xpath("cda:#{element_name}/cda:low")
|
@@ -17,18 +17,15 @@ module HealthDataStandards
|
|
17
17
|
extract_code(encounter_element, encounter, "./gc32:admissionType", :admit_type)
|
18
18
|
extract_code(encounter_element, encounter, "./gc32:reasonForVisit", :reason)
|
19
19
|
extract_code(encounter_element, encounter)
|
20
|
-
extract_facility(encounter_element, encounter)
|
21
20
|
extract_free_text(encounter_element, encounter)
|
22
21
|
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
def extract_facility(encounter_element, encounter)
|
27
|
-
facility_element = encounter_element.xpath("./gc32:facility").first
|
22
|
+
facility_element = encounter_element.at_xpath("./gc32:facility")
|
28
23
|
if facility_element
|
29
|
-
|
30
|
-
encounter.facility =
|
24
|
+
facility = extract_facility(facility_element)
|
25
|
+
encounter.facility = facility
|
31
26
|
end
|
27
|
+
|
28
|
+
encounter
|
32
29
|
end
|
33
30
|
|
34
31
|
end
|
@@ -122,6 +122,22 @@ module HealthDataStandards
|
|
122
122
|
|
123
123
|
return organization
|
124
124
|
end
|
125
|
+
|
126
|
+
def extract_facility(facility_element)
|
127
|
+
facility = Facility.new
|
128
|
+
facility.name = extract_node_text(facility_element.xpath("./gc32:name"))
|
129
|
+
facility.addresses = facility_element.xpath("./gc32:address").map { |addr| extract_address(addr) }
|
130
|
+
facility.telecoms = facility_element.xpath("./gc32:telecom").map { |tele| extract_telecom(tele) }
|
131
|
+
start_time = facility_element.at_xpath("./gc32:duration/gc32:start").try(:text)
|
132
|
+
if start_time
|
133
|
+
facility.start_time = Time.parse(start_time).utc.to_i
|
134
|
+
end
|
135
|
+
end_time = facility_element.at_xpath("./gc32:duration/gc32:end").try(:text)
|
136
|
+
if end_time
|
137
|
+
facility.end_time = Time.parse(end_time).utc.to_i
|
138
|
+
end
|
139
|
+
facility
|
140
|
+
end
|
125
141
|
|
126
142
|
def extract_address(address_element)
|
127
143
|
return unless address_element
|
@@ -1,5 +1,9 @@
|
|
1
1
|
class Procedure < Entry
|
2
|
-
field :site,
|
2
|
+
field :site, type: Hash
|
3
|
+
field :incisionDateTime, type: Integer
|
3
4
|
|
4
5
|
belongs_to :performer, class_name: "Provider"
|
6
|
+
|
7
|
+
alias :incision_date_time :incisionDateTime
|
8
|
+
alias :incision_date_time= :incisionDateTime=
|
5
9
|
end
|
@@ -37,8 +37,8 @@ class Record
|
|
37
37
|
embeds_many :functional_statuses
|
38
38
|
|
39
39
|
Sections = [:allergies, :care_goals, :conditions, :encounters, :immunizations, :medical_equipment,
|
40
|
-
:medications, :procedures, :results, :social_history, :vital_signs, :support, :
|
41
|
-
:functional_statuses]
|
40
|
+
:medications, :procedures, :results, :social_history, :vital_signs, :support, :advance_directives,
|
41
|
+
:insurance_providers, :functional_statuses]
|
42
42
|
|
43
43
|
embeds_many :provider_performances
|
44
44
|
|
@@ -52,6 +52,18 @@ class Record
|
|
52
52
|
def over_18?
|
53
53
|
Time.at(birthdate) < Time.now.years_ago(18)
|
54
54
|
end
|
55
|
+
|
56
|
+
def entries_for_oid(oid)
|
57
|
+
matching_entries_by_section = Sections.map do |section|
|
58
|
+
section_entries = self.send(section)
|
59
|
+
if section_entries.present?
|
60
|
+
section_entries.find_all { |entry| entry.oid == oid }
|
61
|
+
else
|
62
|
+
[]
|
63
|
+
end
|
64
|
+
end
|
65
|
+
matching_entries_by_section.flatten
|
66
|
+
end
|
55
67
|
|
56
68
|
alias :clinical_trial_participant :clinicalTrialParticipant
|
57
69
|
alias :clinical_trial_participant= :clinicalTrialParticipant=
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module HealthDataStandards
|
2
|
+
module SVS
|
3
|
+
|
4
|
+
class Concept
|
5
|
+
|
6
|
+
include Mongoid::Document
|
7
|
+
field :code, type: String
|
8
|
+
field :code_system_name, type: String
|
9
|
+
field :code_system_version, type: String
|
10
|
+
field :display_name, type: String
|
11
|
+
field :code_system, type: String
|
12
|
+
scope :by_code_system_name, ->(cs){where(code_system_name: cs)}
|
13
|
+
scope :by_code_system, ->(cs){where(code_system: cs)}
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module HealthDataStandards
|
2
|
+
module SVS
|
3
|
+
class ValueSet
|
4
|
+
|
5
|
+
include Mongoid::Document
|
6
|
+
field :oid, type: String
|
7
|
+
field :display_name, type: String
|
8
|
+
field :version, type: String
|
9
|
+
|
10
|
+
embeds_many :concepts
|
11
|
+
scope :by_oid, ->(oid){where(:oid => oid)}
|
12
|
+
|
13
|
+
def self.load_from_xml(doc)
|
14
|
+
doc.root.add_namespace_definition("vs","urn:ihe:iti:svs:2008")
|
15
|
+
vs_element = doc.at_xpath("/vs:RetrieveValueSetResponse/vs:ValueSet")
|
16
|
+
if vs_element
|
17
|
+
vs = ValueSet.new(oid: vs_element["ID"], display_name: vs_element["displayName"], version: vs_element["version"])
|
18
|
+
concepts = vs_element.xpath("//vs:Concept").collect do |con|
|
19
|
+
Concept.new(code: con["code"],
|
20
|
+
code_system_name: con["codeSystemName"],
|
21
|
+
code_system_version: con["code_system_version"],
|
22
|
+
display_name: con["displayName"],code_system: con["codeSystem"])
|
23
|
+
end
|
24
|
+
vs.concepts = concepts
|
25
|
+
return vs
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -18,7 +18,9 @@ module HealthDataStandards
|
|
18
18
|
'2.16.840.1.113883.3.88.12.80.20' => 'FDA',
|
19
19
|
'2.16.840.1.113883.5.14' => 'HL7 ActStatus',
|
20
20
|
'2.16.840.1.113883.6.259' => 'HL7 Healthcare Service Location',
|
21
|
-
'2.16.840.1.113883.5.4' => 'HL7 Act Code'
|
21
|
+
'2.16.840.1.113883.5.4' => 'HL7 Act Code',
|
22
|
+
'2.16.840.1.113883.1.11.18877' => 'HL7 Relationship Code',
|
23
|
+
'2.16.840.1.113883.6.238' => 'CDC Race'
|
22
24
|
}
|
23
25
|
|
24
26
|
# Returns the name of a code system given an oid
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module HealthDataStandards
|
2
|
+
module Util
|
3
|
+
# General helpers for working with codes and code systems
|
4
|
+
class HQMFTemplateHelper
|
5
|
+
|
6
|
+
def self.definition_for_template_id(template_id)
|
7
|
+
template_id_map[template_id]
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.template_id_map
|
11
|
+
if @id_map.blank?
|
12
|
+
template_id_file = File.expand_path('../hqmf_template_oid_map.json', __FILE__)
|
13
|
+
@id_map = JSON.parse(File.read(template_id_file))
|
14
|
+
end
|
15
|
+
@id_map
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.template_id_by_definition_and_status(definition, status, negation=false)
|
19
|
+
pairs = template_id_map.select {|k, v| v['definition'] == definition &&
|
20
|
+
v['status'] == status &&
|
21
|
+
v['negation'] == negation}
|
22
|
+
pairs.keys.first if pairs.present?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'uri'
|
3
|
+
module HealthDataStandards
|
4
|
+
module Util
|
5
|
+
class VSApi
|
6
|
+
attr_accessor :api_url, :ticket_url, :username, :password
|
7
|
+
|
8
|
+
def initialize(ticket_url, api_url,username,password)
|
9
|
+
@api_url = api_url
|
10
|
+
@ticket_url = ticket_url
|
11
|
+
@username = username
|
12
|
+
@password = password
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_valueset(oid,&block)
|
16
|
+
vs = RestClient.get api_url, {:params=>{id: oid, ticket: get_ticket}}
|
17
|
+
yield oid,vs if block_given?
|
18
|
+
vs
|
19
|
+
end
|
20
|
+
|
21
|
+
def process_valuesets(oids, &block)
|
22
|
+
oids.each do |oid|
|
23
|
+
vs = get_valueset(oid)
|
24
|
+
yield oid,vs
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def proxy_ticket
|
29
|
+
@proxy_ticket ||= get_proxy_ticket
|
30
|
+
end
|
31
|
+
|
32
|
+
def get_proxy_ticket
|
33
|
+
# the content type is set and the body is a string becuase the NLM service does not support urlencoded content and
|
34
|
+
# throws an error on that contnet type
|
35
|
+
RestClient.post ticket_url, {username: username, password: password}
|
36
|
+
end
|
37
|
+
|
38
|
+
def get_ticket
|
39
|
+
RestClient.post "#{ticket_url}/#{proxy_ticket}", {service: "http://umlsks.nlm.nih.gov"}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: health-data-standards
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,8 +12,24 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-
|
15
|
+
date: 2012-10-31 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: rest-client
|
19
|
+
requirement: !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 1.6.7
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.6.7
|
17
33
|
- !ruby/object:Gem::Dependency
|
18
34
|
name: erubis
|
19
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -196,13 +212,16 @@ files:
|
|
196
212
|
- lib/health-data-standards/models/record.rb
|
197
213
|
- lib/health-data-standards/models/result_value.rb
|
198
214
|
- lib/health-data-standards/models/support.rb
|
215
|
+
- lib/health-data-standards/models/svs/concept.rb
|
216
|
+
- lib/health-data-standards/models/svs/value_set.rb
|
199
217
|
- lib/health-data-standards/models/telecom.rb
|
200
218
|
- lib/health-data-standards/models/thing_with_codes.rb
|
201
219
|
- lib/health-data-standards/models/treating_provider.rb
|
202
220
|
- lib/health-data-standards/models/vital_sign.rb
|
203
221
|
- lib/health-data-standards/util/code_system_helper.rb
|
204
222
|
- lib/health-data-standards/util/hl7_helper.rb
|
205
|
-
- lib/health-data-standards/util/
|
223
|
+
- lib/health-data-standards/util/hqmf_template_helper.rb
|
224
|
+
- lib/health-data-standards/util/vs_api.rb
|
206
225
|
- lib/health-data-standards.rb
|
207
226
|
- templates/_address.gc32.erb
|
208
227
|
- templates/_advance_directive.gc32.erb
|
@@ -273,3 +292,4 @@ signing_key:
|
|
273
292
|
specification_version: 3
|
274
293
|
summary: A library for generating and consuming various healthcare related formats.
|
275
294
|
test_files: []
|
295
|
+
has_rdoc:
|
@@ -1,20 +0,0 @@
|
|
1
|
-
|
2
|
-
module HealthDataStandards
|
3
|
-
module Util
|
4
|
-
# General helpers for working with codes and code systems
|
5
|
-
class QRDATemplateHelper
|
6
|
-
|
7
|
-
def self.definition_for_template_id(template_id)
|
8
|
-
template_id_map[template_id]
|
9
|
-
end
|
10
|
-
|
11
|
-
def self.template_id_map
|
12
|
-
template_id_file = File.expand_path('../qrda_template_oid_map.json', __FILE__)
|
13
|
-
JSON.parse(File.read(template_id_file))
|
14
|
-
end
|
15
|
-
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
|