health-data-standards 3.0.6 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/README.md +3 -1
  2. data/Rakefile +2 -0
  3. data/lib/health-data-standards.rb +10 -0
  4. data/lib/health-data-standards/export/cat_3.rb +24 -0
  5. data/lib/health-data-standards/export/html.rb +2 -1
  6. data/lib/health-data-standards/import/bundle/importer.rb +178 -146
  7. data/lib/health-data-standards/import/cat1/diagnosis_active_importer.rb +0 -5
  8. data/lib/health-data-standards/import/cat1/diagnosis_inactive_importer.rb +1 -6
  9. data/lib/health-data-standards/import/cat1/diagnostic_study_order_importer.rb +0 -4
  10. data/lib/health-data-standards/import/cat1/ecog_status_importer.rb +12 -0
  11. data/lib/health-data-standards/import/cat1/encounter_order_importer.rb +0 -5
  12. data/lib/health-data-standards/import/cat1/lab_order_importer.rb +1 -5
  13. data/lib/health-data-standards/import/cat1/lab_result_importer.rb +18 -0
  14. data/lib/health-data-standards/import/cat1/medication_active_importer.rb +27 -0
  15. data/lib/health-data-standards/import/cat1/patient_importer.rb +54 -46
  16. data/lib/health-data-standards/import/cat1/procedure_performed_importer.rb +28 -0
  17. data/lib/health-data-standards/import/cat1/symptom_active_importer.rb +12 -0
  18. data/lib/health-data-standards/import/cda/condition_importer.rb +2 -0
  19. data/lib/health-data-standards/import/cda/encounter_importer.rb +6 -0
  20. data/lib/health-data-standards/import/cda/procedure_importer.rb +1 -0
  21. data/lib/health-data-standards/import/cda/section_importer.rb +27 -5
  22. data/lib/health-data-standards/models/cda_identifier.rb +17 -0
  23. data/lib/health-data-standards/models/cqm/aggregate_objects.rb +92 -0
  24. data/lib/health-data-standards/models/cqm/measure.rb +51 -30
  25. data/lib/health-data-standards/models/cqm/query_cache.rb +64 -0
  26. data/lib/health-data-standards/models/entry.rb +1 -1
  27. data/lib/health-data-standards/models/record.rb +28 -3
  28. data/lib/health-data-standards/models/svs/value_set.rb +20 -0
  29. data/lib/health-data-standards/tasks/bundle.rake +18 -8
  30. data/lib/health-data-standards/util/hqmf_template_helper.rb +6 -2
  31. data/lib/health-data-standards/util/hqmf_template_oid_map.json +4 -0
  32. data/lib/health-data-standards/util/vs_api.rb +9 -6
  33. data/lib/hqmf-model/data_criteria.json +10 -10
  34. data/lib/hqmf-parser.rb +0 -2
  35. data/lib/hqmf-parser/1.0/range.rb +21 -9
  36. data/templates/c32/show.c32.erb +1 -1
  37. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.4.cat1.erb +1 -0
  38. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.40.cat1.erb +2 -1
  39. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.44.cat1.erb +1 -0
  40. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.46.cat1.erb +1 -1
  41. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.54.cat1.erb +16 -1
  42. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.62.cat1.erb +1 -1
  43. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.69.cat1.erb +7 -2
  44. data/templates/cat1/_2.16.840.1.113883.10.20.24.3.76.cat1.erb +2 -1
  45. data/templates/cat1/_medication_details.cat1.erb +4 -4
  46. data/templates/cat1/_record_target.cat1.erb +2 -2
  47. data/templates/cat1/_result_value.cat1.erb +1 -1
  48. data/templates/cat1/show.cat1.erb +2 -2
  49. data/templates/cat3/_continuous_variable_value.cat3.erb +20 -0
  50. data/templates/cat3/_measure_data.cat3.erb +126 -0
  51. data/templates/cat3/_performance_rate.cat3.erb +16 -0
  52. data/templates/cat3/_supplemental_data.cat3.erb +36 -0
  53. data/templates/cat3/show.cat3.erb +157 -0
  54. data/templates/ccda/show.ccda.erb +1 -1
  55. metadata +25 -45
  56. data/lib/hqmf-parser/value_sets/value_set_parser.rb +0 -241
@@ -4,7 +4,7 @@
4
4
  <typeId root="2.16.840.1.113883.1.3" extension="POCD_HD000040"/>
5
5
  <templateId root="2.16.840.1.113883.10.20.22.1.1" />
6
6
  <templateId root='2.16.840.1.113883.10.20.22.1.2'/>
7
- <id root="2.16.840.1.113883.3.72" extension="<%= patient.id %>" assigningAuthorityName="NIST Healthcare Project"/>
7
+ <id root="2.16.840.1.113883.19.5" extension="<%= patient.id %>" assigningAuthorityName="Cypress Project"/>
8
8
  <code code="34133-9" displayName="Summarization of episode note" codeSystem="2.16.840.1.113883.6.1" codeSystemName="LOINC"/>
9
9
  <title>Cypress C32 Patient Test Record: <%= patient.first %> <%= patient.last %></title>
10
10
  <effectiveTime value="<%= Time.now.utc.to_formatted_s(:number) %>"/>
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: 3.0.6
4
+ version: 3.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2013-02-28 00:00:00.000000000 Z
16
+ date: 2013-04-22 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: rest-client
@@ -144,61 +144,29 @@ dependencies:
144
144
  - !ruby/object:Gem::Version
145
145
  version: '0'
146
146
  - !ruby/object:Gem::Dependency
147
- name: spreadsheet
148
- requirement: !ruby/object:Gem::Requirement
149
- none: false
150
- requirements:
151
- - - '='
152
- - !ruby/object:Gem::Version
153
- version: 0.6.8
154
- type: :runtime
155
- prerelease: false
156
- version_requirements: !ruby/object:Gem::Requirement
157
- none: false
158
- requirements:
159
- - - '='
160
- - !ruby/object:Gem::Version
161
- version: 0.6.8
162
- - !ruby/object:Gem::Dependency
163
- name: google-spreadsheet-ruby
164
- requirement: !ruby/object:Gem::Requirement
165
- none: false
166
- requirements:
167
- - - '='
168
- - !ruby/object:Gem::Version
169
- version: 0.1.8
170
- type: :runtime
171
- prerelease: false
172
- version_requirements: !ruby/object:Gem::Requirement
173
- none: false
174
- requirements:
175
- - - '='
176
- - !ruby/object:Gem::Version
177
- version: 0.1.8
178
- - !ruby/object:Gem::Dependency
179
- name: roo
147
+ name: log4r
180
148
  requirement: !ruby/object:Gem::Requirement
181
149
  none: false
182
150
  requirements:
183
- - - '='
151
+ - - ~>
184
152
  - !ruby/object:Gem::Version
185
- version: 1.10.1
153
+ version: 1.1.10
186
154
  type: :runtime
187
155
  prerelease: false
188
156
  version_requirements: !ruby/object:Gem::Requirement
189
157
  none: false
190
158
  requirements:
191
- - - '='
159
+ - - ~>
192
160
  - !ruby/object:Gem::Version
193
- version: 1.10.1
161
+ version: 1.1.10
194
162
  - !ruby/object:Gem::Dependency
195
- name: log4r
163
+ name: memoist
196
164
  requirement: !ruby/object:Gem::Requirement
197
165
  none: false
198
166
  requirements:
199
167
  - - ~>
200
168
  - !ruby/object:Gem::Version
201
- version: 1.1.10
169
+ version: 0.9.0
202
170
  type: :runtime
203
171
  prerelease: false
204
172
  version_requirements: !ruby/object:Gem::Requirement
@@ -206,7 +174,7 @@ dependencies:
206
174
  requirements:
207
175
  - - ~>
208
176
  - !ruby/object:Gem::Version
209
- version: 1.1.10
177
+ version: 0.9.0
210
178
  description: A library for generating and consuming various healthcare related formats.
211
179
  This includes HITSP C32, ASTM CCR and PQRI.
212
180
  email: talk@projectpophealth.org
@@ -216,6 +184,7 @@ extra_rdoc_files: []
216
184
  files:
217
185
  - lib/health-data-standards/export/c32.rb
218
186
  - lib/health-data-standards/export/cat_1.rb
187
+ - lib/health-data-standards/export/cat_3.rb
219
188
  - lib/health-data-standards/export/ccda.rb
220
189
  - lib/health-data-standards/export/ccr.rb
221
190
  - lib/health-data-standards/export/csv.rb
@@ -242,14 +211,19 @@ files:
242
211
  - lib/health-data-standards/import/cat1/diagnosis_active_importer.rb
243
212
  - lib/health-data-standards/import/cat1/diagnosis_inactive_importer.rb
244
213
  - lib/health-data-standards/import/cat1/diagnostic_study_order_importer.rb
214
+ - lib/health-data-standards/import/cat1/ecog_status_importer.rb
245
215
  - lib/health-data-standards/import/cat1/encounter_order_importer.rb
246
216
  - lib/health-data-standards/import/cat1/entry_package.rb
247
217
  - lib/health-data-standards/import/cat1/gestational_age_importer.rb
248
218
  - lib/health-data-standards/import/cat1/lab_order_importer.rb
219
+ - lib/health-data-standards/import/cat1/lab_result_importer.rb
220
+ - lib/health-data-standards/import/cat1/medication_active_importer.rb
249
221
  - lib/health-data-standards/import/cat1/medication_dispensed_importer.rb
250
222
  - lib/health-data-standards/import/cat1/patient_importer.rb
251
223
  - lib/health-data-standards/import/cat1/procedure_intolerance_importer.rb
252
224
  - lib/health-data-standards/import/cat1/procedure_order_importer.rb
225
+ - lib/health-data-standards/import/cat1/procedure_performed_importer.rb
226
+ - lib/health-data-standards/import/cat1/symptom_active_importer.rb
253
227
  - lib/health-data-standards/import/cat1/tobacco_use_importer.rb
254
228
  - lib/health-data-standards/import/ccda/allergy_importer.rb
255
229
  - lib/health-data-standards/import/ccda/care_goal_importer.rb
@@ -302,10 +276,13 @@ files:
302
276
  - lib/health-data-standards/import/provider_import_utils.rb
303
277
  - lib/health-data-standards/models/address.rb
304
278
  - lib/health-data-standards/models/allergy.rb
279
+ - lib/health-data-standards/models/cda_identifier.rb
305
280
  - lib/health-data-standards/models/coded_result_value.rb
306
281
  - lib/health-data-standards/models/condition.rb
282
+ - lib/health-data-standards/models/cqm/aggregate_objects.rb
307
283
  - lib/health-data-standards/models/cqm/bundle.rb
308
284
  - lib/health-data-standards/models/cqm/measure.rb
285
+ - lib/health-data-standards/models/cqm/query_cache.rb
309
286
  - lib/health-data-standards/models/encounter.rb
310
287
  - lib/health-data-standards/models/entry.rb
311
288
  - lib/health-data-standards/models/facility.rb
@@ -383,7 +360,6 @@ files:
383
360
  - lib/hqmf-parser/converter/pass2/comparison_converter.rb
384
361
  - lib/hqmf-parser/converter/pass2/operator_converter.rb
385
362
  - lib/hqmf-parser/parser.rb
386
- - lib/hqmf-parser/value_sets/value_set_parser.rb
387
363
  - lib/hqmf-parser.rb
388
364
  - lib/util/counter.rb
389
365
  - templates/_pedigree.hdata.erb
@@ -456,6 +432,11 @@ files:
456
432
  - templates/cat1/_reporting_parameters.cat1.erb
457
433
  - templates/cat1/_result_value.cat1.erb
458
434
  - templates/cat1/show.cat1.erb
435
+ - templates/cat3/_continuous_variable_value.cat3.erb
436
+ - templates/cat3/_measure_data.cat3.erb
437
+ - templates/cat3/_performance_rate.cat3.erb
438
+ - templates/cat3/_supplemental_data.cat3.erb
439
+ - templates/cat3/show.cat3.erb
459
440
  - templates/ccda/_allergies.ccda.erb
460
441
  - templates/ccda/_allergies_no_current.ccda.erb
461
442
  - templates/ccda/_care_goals.ccda.erb
@@ -559,9 +540,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
559
540
  version: '0'
560
541
  requirements: []
561
542
  rubyforge_project:
562
- rubygems_version: 1.8.24
543
+ rubygems_version: 1.8.25
563
544
  signing_key:
564
545
  specification_version: 3
565
546
  summary: A library for generating and consuming various healthcare related formats.
566
547
  test_files: []
567
- has_rdoc:
@@ -1,241 +0,0 @@
1
- require 'zip/zipfilesystem'
2
- require 'spreadsheet'
3
- require 'google_spreadsheet'
4
- require 'roo'
5
- require 'iconv'
6
-
7
- module HQMF
8
- module ValueSet
9
- class Parser
10
-
11
- attr_accessor :child_oids
12
-
13
- GROUP_CODE_SET = "GROUPING"
14
-
15
- ORGANIZATION_TITLE = "Value Set Developer"
16
- OID_TITLE = "Value Set OID"
17
- CONCEPT_TITLE = "Value Set Name"
18
- CATEGORY_TITLE = "QDM Category"
19
- CODE_SET_TITLE ="Code System"
20
- VERSION_TITLE = "Code System Version"
21
- CODE_TITLE = "Code"
22
- DESCRIPTION_TITLE = "Descriptor"
23
-
24
- CODE_SYSTEM_NORMALIZER = {
25
- 'ICD-9'=>'ICD-9-CM',
26
- 'ICD-10'=>'ICD-10-CM',
27
- 'HL7 (2.16.840.1.113883.5.1)'=>'HL7'
28
- }
29
- IGNORED_CODE_SYSTEM_NAMES = ['Grouping', 'GROUPING' ,'HL7', "Administrative Sex"]
30
-
31
- def initialize()
32
- @child_oids = []
33
- end
34
-
35
- # import an excel matrix array into mongo
36
- def parse(file, options={})
37
- sheet_array = file_to_array(file, options)
38
- by_oid_ungrouped = cells_to_hashs_by_oid(sheet_array)
39
- value_sets = collapse_groups(by_oid_ungrouped)
40
- translate_json(value_sets)
41
- end
42
-
43
- def collapse_groups(by_oid_ungrouped)
44
-
45
- final = []
46
-
47
- # select the grouped code sets and fill in the children... also remove the children that are a
48
- # member of a group. We remove the children so that we can create parent groups for the orphans
49
- (by_oid_ungrouped.select {|key,value| value["code_set"].upcase == GROUP_CODE_SET}).each do |key, value|
50
- # remove the group so that it is not in the orphan list
51
- by_oid_ungrouped.delete(value["oid"])
52
- codes = []
53
- value["codes"].each do |child_oid|
54
- # codes << by_oid_ungrouped.delete(child_oid)
55
- # do not delete the children of a group. These may be referenced by other groups or directly by the measure
56
- code = by_oid_ungrouped[child_oid]
57
- @child_oids << child_oid
58
- puts "\tcode could not be found: #{child_oid}" unless code
59
- codes << code if code
60
- # for hierarchies we need to probably have codes be a hash that we select from if we don't find the
61
- # element in by_oid_ungrouped we may need to look for it in final
62
- end
63
- value["code_sets"] = codes
64
- value.delete("codes")
65
- value.delete("code_set")
66
- final << value
67
- end
68
-
69
- # fill out the orphans
70
- by_oid_ungrouped.each do |key, orphan|
71
- final << adopt_orphan(orphan)
72
- end
73
-
74
- deleted = []
75
- final.delete_if {|x| to_delete = x['code_sets'].nil? || x['code_sets'].empty?; deleted << x if to_delete; to_delete }
76
- deleted.each do |value|
77
- puts "\tDeleted value set with no code sets: #{value['oid']}"
78
- end
79
- final
80
-
81
- end
82
-
83
- def adopt_orphan(orphan)
84
- parent = orphan.dup
85
- parent["code_sets"] = [orphan]
86
- parent.delete("codes")
87
- parent.delete("code_set")
88
- parent
89
- end
90
-
91
- # take an excel matrix array and turn it into an array of db models
92
- def cells_to_hashs_by_oid(array)
93
- a = Array.new(array) # new variable for reentrant
94
- headers = a.shift.map {|i| i.to_s } # because of this shift
95
- string_data = a.map {|row| row.map {|cell| cell.to_s } }
96
- array_of_hashes = string_data.map {|row| Hash[*headers.zip(row).flatten] }
97
-
98
- by_oid = {}
99
- array_of_hashes.each do |row|
100
- entry = convert_row(row)
101
-
102
- existing = by_oid[entry["oid"]]
103
- if (existing)
104
- existing["codes"].concat(entry["codes"])
105
- else
106
- by_oid[entry["oid"]] = entry
107
- end
108
- end
109
-
110
- by_oid
111
- end
112
-
113
- def self.get_format(file_path)
114
- if file_path =~ /xls$/
115
- :xls
116
- elsif file_path =~ /xlsx$/
117
- :xlsx
118
- end
119
- end
120
-
121
- private
122
-
123
- def convert_row(row)
124
- # Value Set Developer
125
- # Value Set OID
126
- # Value Set Name
127
- # QDM Category
128
- # Code System
129
- # Code System Version
130
- # Code
131
- # Descriptor
132
- value = {
133
- "key" => normalize_names(row[CATEGORY_TITLE],row[CONCEPT_TITLE]),
134
- "organization" => row[ORGANIZATION_TITLE],
135
- "oid" => row[OID_TITLE].strip.gsub(/[^0-9\.]/i, ''),
136
- "concept" => normalize_names(row[CONCEPT_TITLE]),
137
- "category" => normalize_names(row[CATEGORY_TITLE]),
138
- "code_set" => normalize_code_system(row[CODE_SET_TITLE]),
139
- "version" => row[VERSION_TITLE],
140
- "codes" => extract_code(row[CODE_TITLE], row[CODE_SET_TITLE]),
141
- "description" => row[DESCRIPTION_TITLE]
142
- }
143
- value['codes'].map! {|code| code.strip.gsub(/[^0-9\.]/i, '')} if (value['code_set'].upcase == GROUP_CODE_SET)
144
- value
145
- end
146
-
147
- # Break all the supplied strings into separate words and return the resulting list as a
148
- # new string with each word separated with '_'
149
- def normalize_names(*components)
150
- name = []
151
- components.each do |component|
152
- name.concat component.gsub(/\W/,' ').split.collect { |word| word.strip.downcase }
153
- end
154
- name.join '_'
155
- end
156
-
157
- def normalize_code_system(code_system_name)
158
- code_system_name = CODE_SYSTEM_NORMALIZER[code_system_name] if CODE_SYSTEM_NORMALIZER[code_system_name]
159
- return code_system_name if IGNORED_CODE_SYSTEM_NAMES.include? code_system_name
160
- oid = HealthDataStandards::Util::CodeSystemHelper.oid_for_code_system(code_system_name)
161
- puts "\tbad code system name: #{code_system_name}" unless oid
162
- code_system_name
163
- end
164
-
165
- def extract_code(code, set)
166
-
167
- code.strip!
168
- if set=='CPT' && code.include?('-')
169
- eval(code.strip.gsub('-','..')).to_a.collect { |i| i.to_s }
170
- else
171
- [code]
172
- end
173
-
174
- end
175
-
176
- def file_to_array(file_path, options)
177
- defaults = {
178
- :columns => 2, # range of import
179
- :sheet => 1 # only one sheet at a time can be worked on
180
- }
181
- options = defaults.merge(options)
182
-
183
- book = book_by_format(file_path, options[:format])
184
- book.default_sheet=book.sheets[options[:sheet]]
185
-
186
- # catch double byte encoding problems in spreadsheet files
187
- # Encoding::InvalidByteSequenceError: "\x9E\xDE" on UTF-16LE
188
- begin
189
- book.to_matrix.to_a
190
- rescue Encoding::InvalidByteSequenceError => e
191
- raise "Spreadsheet encoding problem: #{e}"
192
- end
193
- end
194
-
195
- def book_by_format(file_path, format)
196
- format = HQMF::ValueSet::Parser.get_format(file_path) unless format
197
-
198
- if format == :xls
199
- book = Excel.new(file_path, nil, :ignore)
200
- elsif format == :xlsx
201
- book = Excelx.new(file_path, nil, :ignore)
202
- else
203
- raise "File does not end in .xls or .xlsx"
204
- end
205
- book
206
- end
207
-
208
- def translate_json(value_sets)
209
- value_set_models = []
210
-
211
- value_sets.each do |value_set|
212
- hds_value_set = HealthDataStandards::SVS::ValueSet.new()
213
- hds_value_set['oid'] = value_set['oid']
214
- hds_value_set['display_name'] = value_set['key']
215
- hds_value_set['version'] = value_set['version']
216
- hds_value_set['concepts'] = []
217
-
218
- value_set['code_sets'].each do |code_set|
219
- code_set['codes'].map{ |code|
220
- concept = HealthDataStandards::SVS::Concept.new()
221
- concept['code'] = code
222
- concept['code_system'] = nil
223
- concept['code_system_name'] = code_set['code_set']
224
- concept['code_system_version'] = code_set['version']
225
- concept['display_name'] = nil
226
- hds_value_set['concepts'].concat([concept])
227
- }
228
- end
229
- if hds_value_set['concepts'].include? nil
230
- puts "Value Set has a bad code set (code set is null)"
231
- hds_value_set['concepts'].compact!
232
- end
233
- value_set_models << hds_value_set
234
- end
235
- value_set_models
236
- end
237
-
238
-
239
- end
240
- end
241
- end