ncs_mdes 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ##
4
+ # A script to generate disposition_codes.yml from the MDES 2.2
5
+ # spreadsheet's Dispositions tab.
6
+ #
7
+ # This script requires the 'roo' gem, which is not included in
8
+ # ncs_mdes's gemspec because it has a huge number of dependencies and
9
+ # is not needed at runtime.
10
+
11
+ require 'rubygems'
12
+ require 'roo'
13
+ require 'yaml'
14
+
15
+ MDES_XLSX = ARGV.first or fail 'Please provide the path to the MDES spreadsheet'
16
+ TARGET = File.expand_path('../disposition_codes.yml', __FILE__)
17
+ SHEET_NAME = 'Dispositions'
18
+
19
+ MAPPED_COLUMNS = {
20
+ 'A' => 'final_category',
21
+ 'B' => 'sub_category',
22
+ 'C' => 'disposition'
23
+ }
24
+
25
+ def normalize_whitespace(s)
26
+ s.strip.gsub(/\s+/, " ")
27
+ end
28
+
29
+ book = Excelx.new(MDES_XLSX)
30
+
31
+ # This is the array of hashes that will eventually be serialized to
32
+ # disposition_codes.yml.
33
+ dispositions = []
34
+
35
+ current_event = nil
36
+ current_category_code = nil
37
+ 1.upto(book.last_row(SHEET_NAME)) do |row_number|
38
+ a, b = %w(A B).collect { |col| book.cell(row_number, col, SHEET_NAME) }
39
+ if a =~ /Category\s+(\d)\s+\((.*?)\)\s+Disposition\s+Codes/
40
+ current_event = normalize_whitespace $2
41
+ current_category_code = $1.to_i
42
+ puts "Collecting for category #{current_event} (#{current_category_code})"
43
+ elsif b =~ /\S/ && a !~ /FINAL/
44
+ disposition_hash = MAPPED_COLUMNS.inject({}) do |h, (col, key)|
45
+ h[key] = normalize_whitespace(book.cell(row_number, col, SHEET_NAME)); h
46
+ end
47
+ disposition_hash['event'] = current_event
48
+ disposition_hash['category_code'] = current_category_code
49
+ disposition_hash['interim_code'], disposition_hash['final_code'] =
50
+ normalize_whitespace(book.cell(row_number, 'D', SHEET_NAME)).split('/')
51
+
52
+ puts disposition_hash.inspect if disposition_hash['interim_code'] =~ /^02/
53
+ dispositions << disposition_hash
54
+ end
55
+ end
56
+
57
+ File.open(TARGET, 'w') { |f| f.write dispositions.to_yaml }
@@ -0,0 +1,452 @@
1
+ foreign_keys:
2
+ birth_visit:
3
+ new_address_id: address
4
+ mail_address_id: address
5
+ new_address_b_id: address
6
+
7
+ birth_visit_2:
8
+ new_address_id: address
9
+ mail_address_id: address
10
+ new_address_b_id: address
11
+
12
+ birth_visit_baby_name:
13
+ bv_id: birth_visit
14
+
15
+ birth_visit_baby_name_2:
16
+ bv_id: birth_visit_2
17
+
18
+ birth_visit_decorate_room:
19
+ bv_id: birth_visit
20
+
21
+ birth_visit_decorate_room_2:
22
+ bv_id: birth_visit_2
23
+
24
+ birth_visit_li:
25
+ new_address_id: address
26
+ mail_address_id: address
27
+ new_address_b_id: address
28
+
29
+ birth_visit_renovate_room:
30
+ bv_id: birth_visit
31
+
32
+ birth_visit_renovate_room_2:
33
+ bv_id: birth_visit_2
34
+
35
+ drf_therm_verification:
36
+ equip_id: env_equipment
37
+
38
+ eighteen_mth_mother:
39
+ c_addr1_id: address
40
+ c_addr2_id: address
41
+ r_p_id: participant
42
+
43
+ eighteen_mth_mother_2:
44
+ c_addr1_id: address
45
+ c_addr2_id: address
46
+ r_p_id: participant
47
+
48
+ eighteen_mth_mother_cond:
49
+ eighteen_mth_habits_id: eighteen_mth_mother_habits
50
+
51
+ eighteen_mth_mother_saq:
52
+ asq18_address_id: address
53
+ r_p_id: participant
54
+
55
+ env_equipment_prob_log:
56
+ equip_id: env_equipment
57
+ staff_id_reviewer: staff
58
+
59
+ event:
60
+ participant_id: participant
61
+
62
+ household_enumeration_hidden_du:
63
+ hdu_address_id: address
64
+
65
+ incident:
66
+ inc_staff_reporter_id: staff
67
+ inc_staff_supervisor_id: staff
68
+ inc_recip_is_participant: participant
69
+ inc_recip_is_du: dwelling_unit
70
+ inc_recip_is_staff: staff
71
+ inc_recip_is_family: person
72
+ inc_recip_is_acquaintance: person
73
+ inc_contact_person: person
74
+
75
+ nine_mth_mother:
76
+ r_p_id: participant
77
+
78
+ participant_consent:
79
+ person_who_consented_id: person
80
+ person_wthdrw_consent_id: person
81
+
82
+ participant_vis_consent:
83
+ vis_person_who_consented_id: person
84
+
85
+ participant_rvis:
86
+ rvis_person: person
87
+
88
+ pb_recruitment:
89
+ address_pb_id: address
90
+
91
+ pb_recruitment_2:
92
+ address_pb_id: address
93
+
94
+ pb_recruitment_info_source:
95
+ pb_recruitment_id: pb_recruitment
96
+
97
+ pb_recruitment_info_source_2:
98
+ pb_recruitment_id: pb_recruitment_2
99
+
100
+ pb_recruitment_prov_source:
101
+ pb_recruitment_id: pb_recruitment
102
+
103
+ pb_recruitment_prov_source_2:
104
+ pb_recruitment_id: pb_recruitment_2
105
+
106
+ pb_recruitment_prov_svc:
107
+ pb_recruitment_id: pb_recruitment
108
+
109
+ pb_recruitment_prov_svc_2:
110
+ pb_recruitment_id: pb_recruitment_2
111
+
112
+ person:
113
+ new_address_id: address
114
+
115
+ prec_therm_cert:
116
+ equip_id: env_equipment
117
+
118
+ pre_preg:
119
+ c_addr1_id: address
120
+ c_addr2_id: address
121
+
122
+ preg_screen_eh:
123
+ mail_address_id: address
124
+ new_address_id: address
125
+
126
+ preg_screen_eh_2:
127
+ mail_address_id: address
128
+ new_address_id: address
129
+
130
+ preg_screen_eh_know_ncs:
131
+ ps_eh_id: preg_screen_eh
132
+
133
+ preg_screen_eh_know_ncs_2:
134
+ ps_eh_id: preg_screen_eh_2
135
+
136
+ preg_screen_eh_race:
137
+ ps_eh_id: preg_screen_eh
138
+
139
+ preg_screen_eh_race_2:
140
+ ps_eh_id: preg_screen_eh_2
141
+
142
+ preg_screen_hi:
143
+ mail_address_id: address
144
+ new_address_id: address
145
+
146
+ preg_screen_hi_2:
147
+ mail_address_id: address
148
+ new_address_id: address
149
+
150
+ preg_screen_hi_know_ncs:
151
+ ps_hi_id: preg_screen_hi
152
+
153
+ preg_screen_hi_know_ncs_2:
154
+ ps_hi_id: preg_screen_hi_2
155
+
156
+ preg_screen_hi_race:
157
+ ps_hi_id: preg_screen_hi
158
+
159
+ preg_screen_hi_race_2:
160
+ ps_hi_id: preg_screen_hi_2
161
+
162
+ preg_screen_pb:
163
+ mail_address_id: address
164
+ new_address_id: address
165
+
166
+ preg_screen_pb_2:
167
+ mail_address_id: address
168
+ new_address_id: address
169
+
170
+ preg_screen_pb_know_ncs:
171
+ ps_pb_id: preg_screen_pb
172
+
173
+ preg_screen_pb_know_ncs_2:
174
+ ps_pb_id: preg_screen_pb_2
175
+
176
+ preg_screen_pb_race:
177
+ ps_pb_id: preg_screen_pb
178
+
179
+ preg_screen_pb_race_2:
180
+ ps_pb_id: preg_screen_pb_2
181
+
182
+ preg_visit_1:
183
+ b_address_id: address
184
+ c_addr1_id: address
185
+ c_addr2_id: address
186
+
187
+ preg_visit_1_2:
188
+ b_address_id: address
189
+ c_addr1_id: address
190
+ c_addr2_id: address
191
+
192
+ preg_visit_1_commute:
193
+ pv1_id: preg_visit_1
194
+
195
+ preg_visit_1_commute_2:
196
+ pv1_id: preg_visit_1_2
197
+
198
+ preg_visit_1_cool:
199
+ pv1_id: preg_visit_1
200
+
201
+ preg_visit_1_cool_2:
202
+ pv1_id: preg_visit_1_2
203
+
204
+ preg_visit_1_diagnose_2:
205
+ pv1_id: preg_visit_1
206
+
207
+ preg_visit_1_diagnose_2_2:
208
+ pv1_id: preg_visit_1_2
209
+
210
+ preg_visit_1_heat2:
211
+ pv1_id: preg_visit_1
212
+
213
+ preg_visit_1_heat2_2:
214
+ pv1_id: preg_visit_2
215
+
216
+ preg_visit_1_local_trav:
217
+ pv1_id: preg_visit_1
218
+
219
+ preg_visit_1_local_trav_2:
220
+ pv1_id: preg_visit_1_2
221
+
222
+ preg_visit_1_nonenglish2_2:
223
+ pv1_id: preg_visit_1_2
224
+
225
+ preg_visit_1_pdecorate_room:
226
+ pv1_id: preg_visit_1
227
+
228
+ preg_visit_1_pdecorate_room_2:
229
+ pv1_id: preg_visit_1_2
230
+
231
+ preg_visit_1_pet_type:
232
+ pv1_id: preg_visit_1
233
+
234
+ preg_visit_1_pet_type_2:
235
+ pv1_id: preg_visit_1_2
236
+
237
+ preg_visit_1_prenovate2_room:
238
+ pv1_id: preg_visit_1
239
+
240
+ preg_visit_1_prenovate_room:
241
+ pv1_id: preg_visit_1
242
+
243
+ preg_visit_1_prenovate_room_2:
244
+ pv1_id: preg_visit_1_2
245
+
246
+ preg_visit_1_room_mold:
247
+ pv1_id: preg_visit_1
248
+
249
+ preg_visit_1_room_mold_2:
250
+ pv1_id: preg_visit_1_2
251
+
252
+ preg_visit_1_saq_2:
253
+ f_addr_id: address
254
+
255
+ preg_visit_1_saq_3:
256
+ f_addr_id: address
257
+
258
+ preg_visit_1_sp_race:
259
+ pv1_id: preg_visit_1
260
+
261
+ preg_visit_1_sp_race_2:
262
+ pv1_id: preg_visit_1_2
263
+
264
+ preg_visit_2:
265
+ b_address_id: address
266
+ c_addr1_id: address
267
+ c_addr2_id: address
268
+
269
+ preg_visit_2_2:
270
+ b_address_id: address
271
+ c_addr1_id: address
272
+ c_addr2_id: address
273
+
274
+ preg_visit_2_cool:
275
+ pv2_id: preg_visit_2
276
+
277
+ preg_visit_2_cool_2:
278
+ pv2_id: preg_visit_2_2
279
+
280
+ preg_visit_2_diagnose_2:
281
+ pv2_id: preg_visit_2
282
+
283
+ preg_visit_2_diagnose_2_2:
284
+ pv2_id: preg_visit_2_2
285
+
286
+ preg_visit_2_heat2:
287
+ pv2_id: preg_visit_2
288
+
289
+ preg_visit_2_heat2_2:
290
+ pv2_id: preg_visit_2_2
291
+
292
+ preg_visit_2_pdecorate2_room:
293
+ pv2_id: preg_visit_2
294
+
295
+ preg_visit_2_pdecorate2_room_2:
296
+ pv2_id: preg_visit_2_2
297
+
298
+ preg_visit_2_prenovate_room:
299
+ pv2_id: preg_visit_2
300
+
301
+ preg_visit_2_prenovate_room_2:
302
+ pv2_id: preg_visit_2_2
303
+
304
+ preg_visit_2_room_mold:
305
+ pv2_id: preg_visit_2
306
+
307
+ preg_visit_2_room_mold_2:
308
+ pv2_id: preg_visit_2_2
309
+
310
+ preg_visit_li:
311
+ b_address_id: address
312
+
313
+ preg_visit_li_2:
314
+ b_address_id: address
315
+
316
+ preg_visit_li_cool:
317
+ pv_li_id: preg_visit_li
318
+
319
+ preg_visit_li_cool_2:
320
+ pv_li_id: preg_visit_li_2
321
+
322
+ ref_freezer_verification:
323
+ equip_id: env_equipment
324
+
325
+ sample_receipt_store:
326
+ equip_id: env_equipment
327
+
328
+ sample_shipping:
329
+ staff_id_track: staff
330
+
331
+ six_mth_mother:
332
+ c_addr1_id: address
333
+ c_addr2_id: address
334
+ r_p_id: participant
335
+
336
+ six_mth_saq_formula_type:
337
+ six_mth_saq_id: six_mth_saq
338
+
339
+ six_mth_saq_2:
340
+ r_p_id: participant
341
+
342
+ six_mth_saq_formula_type_2:
343
+ six_mth_saq_id: six_mth_saq_2
344
+
345
+ six_mth_saq_supp:
346
+ six_mth_saq_id: six_mth_saq
347
+
348
+ six_mth_saq_supp_2:
349
+ six_mth_saq_id: six_mth_saq_2
350
+
351
+ six_mth_saq_water:
352
+ six_mth_saq_id: six_mth_saq
353
+
354
+ six_mth_saq_water_2:
355
+ six_mth_saq_id: six_mth_saq_2
356
+
357
+ spec_blood:
358
+ # According to the corresponding instrument, equip_id is manually entered
359
+ # and not a reference to another table.
360
+ equip_id: false
361
+
362
+ spec_blood_2:
363
+ # According to the corresponding instrument, equip_id is manually entered
364
+ # and not a reference to another table.
365
+ equip_id: false
366
+
367
+ spec_cord_blood_specimen:
368
+ spec_cord_blood_id: spec_cord_blood
369
+
370
+ spec_cord_blood_specimen_2:
371
+ spec_cord_blood_id: spec_cord_blood_2
372
+
373
+ spec_receipt:
374
+ # Insufficient info to determine what this is supposed to link to
375
+ storage_container_id: false
376
+ equip_id: spec_equipment
377
+
378
+ spec_shipping:
379
+ # Insufficient info to determine what this is supposed to link to
380
+ shipper_id: false
381
+
382
+ spec_storage:
383
+ equip_id: spec_equipment
384
+
385
+ staff_exp_mngmnt_tasks:
386
+ staff_weekly_expense_id: staff_weekly_expense
387
+
388
+ staff_exp_data_cllctn_tasks:
389
+ staff_weekly_expense_id: staff_weekly_expense
390
+
391
+ three_mth_mother:
392
+ r_p_id: participant
393
+
394
+ trh_meter_calibration:
395
+ equip_id: spec_equipment
396
+
397
+ twelve_mth_mother:
398
+ c_addr1_id: address
399
+ c_addr2_id: address
400
+ r_p_id: participant
401
+
402
+ twelve_mth_saq_2:
403
+ r_p_id: participant
404
+
405
+ twelve_mth_saq_formula_brand:
406
+ twelve_mth_saq_id: twelve_mth_saq
407
+
408
+ twelve_mth_saq_formula_brand_2:
409
+ twelve_mth_saq_id: twelve_mth_saq_2
410
+
411
+ twelve_mth_saq_formula_type:
412
+ twelve_mth_saq_id: twelve_mth_saq
413
+
414
+ twelve_mth_saq_formula_type_2:
415
+ twelve_mth_saq_id: twelve_mth_saq_2
416
+
417
+ twelve_mth_saq_supplement:
418
+ twelve_mth_saq_id: twelve_mth_saq
419
+
420
+ twelve_mth_saq_supplement_2:
421
+ twelve_mth_saq_id: twelve_mth_saq_2
422
+
423
+ twelve_mth_saq_water:
424
+ twelve_mth_saq_id: twelve_mth_saq
425
+
426
+ twelve_mth_saq_water_2:
427
+ twelve_mth_saq_id: twelve_mth_saq_2
428
+
429
+ twenty_four_mth_mother:
430
+ c_addr1_id: address
431
+ c_addr2_id: address
432
+ r_p_id: participant
433
+
434
+ twenty_four_mth_mother_2:
435
+ c_addr1_id: address
436
+ c_addr2_id: address
437
+ r_p_id: participant
438
+
439
+ twenty_four_mth_mother_otc:
440
+ twenty_four_mth_mother_id: twenty_four_mth_mother
441
+
442
+ twenty_four_mth_mother_prescr:
443
+ twenty_four_mth_mother_id: twenty_four_mth_mother
444
+
445
+ twenty_four_mth_mother_suppl:
446
+ twenty_four_mth_mother_id: twenty_four_mth_mother
447
+
448
+ twenty_four_mth_saq:
449
+ asq24_address_id: address
450
+ r_p_id: participant
451
+
452
+
@@ -51,6 +51,10 @@ module NcsNavigator::Mdes
51
51
  create('1.2', '1.2/Data_Transmission_Schema_V1.2.xsd')
52
52
  when '2.0'
53
53
  create('2.0', '2.0/NCS_Transmission_Schema_2.0.01.02.xml', '2.0.01.02')
54
+ when '2.1'
55
+ create('2.1', '2.1/NCS_Transmission_Schema_2.1.00.00.xsd', '2.1.00.00')
56
+ when '2.2'
57
+ create('2.2', '2.2/NCS_Transmission_Schema_2.2.01.00.xsd', '2.2.01.00')
54
58
  else
55
59
  raise "MDES #{version} is not supported by this version of ncs_mdes"
56
60
  end
@@ -91,7 +91,7 @@ module NcsNavigator::Mdes
91
91
  tables.each { |t|
92
92
  fk_overrides = heuristic_overrides['foreign_keys'][t.name] || { }
93
93
  t.variables.each { |v|
94
- v.resolve_foreign_key!(tables, fk_overrides[v.name], :log => @log)
94
+ v.resolve_foreign_key!(tables, fk_overrides[v.name], :log => @log, :in_table => t)
95
95
  }
96
96
  }
97
97
  }
@@ -175,12 +175,13 @@ module NcsNavigator::Mdes
175
175
  # @return [void]
176
176
  def resolve_foreign_key!(tables, override_name=nil, options={})
177
177
  log = options[:log] || NcsNavigator::Mdes.default_logger
178
+ source_table = options[:in_table] ? options[:in_table].name : '[unspecified table]'
178
179
 
179
180
  case override_name
180
181
  when String
181
182
  self.table_reference = tables.detect { |t| t.name == override_name }
182
183
  unless table_reference
183
- log.warn("Foreign key #{name.inspect} explicitly mapped " <<
184
+ log.warn("Foreign key #{name.inspect} in #{source_table} explicitly mapped " <<
184
185
  "to unknown table #{override_name.inspect}.")
185
186
  end
186
187
  when nil
@@ -192,14 +193,15 @@ module NcsNavigator::Mdes
192
193
 
193
194
  case candidates.size
194
195
  when 0
195
- log.warn("Foreign key not resolvable: " <<
196
+ log.warn("Foreign key in #{source_table} not resolvable: " <<
196
197
  "no tables have a primary key named #{name.inspect}.")
197
198
  when 1
198
199
  self.table_reference = candidates.first
199
200
  else
200
201
  log.warn(
201
- "#{candidates.size} possible parent tables found for foreign key #{name.inspect}: " <<
202
- "#{candidates.collect { |c| c.name.inspect }.join(', ')}. None used due to ambiguity.")
202
+ "#{candidates.size} possible parent tables found for foreign key #{name.inspect} " <<
203
+ "in #{source_table}: #{candidates.collect { |c| c.name.inspect }.join(', ')}. " <<
204
+ "None used due to ambiguity.")
203
205
  end
204
206
  end
205
207
  end
@@ -1,5 +1,5 @@
1
1
  module NcsNavigator
2
2
  module Mdes
3
- VERSION = '0.5.0'
3
+ VERSION = '0.6.0'
4
4
  end
5
5
  end
@@ -72,23 +72,29 @@ module NcsNavigator::Mdes
72
72
  end
73
73
 
74
74
  describe '.get' do
75
- describe '1.2' do
76
- subject { SourceDocuments.get('1.2') }
77
-
78
- it 'has the correct path for the schema' do
79
- subject.schema.should =~ %r{1.2/Data_Transmission_Schema_V1.2.xsd$}
80
- end
75
+ shared_examples 'version docs' do
76
+ subject { SourceDocuments.get(version) }
81
77
 
82
78
  it 'has the correct path for the overrides' do
83
- subject.heuristic_overrides.should =~ %r{1.2/heuristic_overrides.yml$}
79
+ subject.heuristic_overrides.should =~ %r{#{version}/heuristic_overrides.yml$}
84
80
  end
85
81
 
86
82
  it 'has the correct path for the disposition codes' do
87
- subject.disposition_codes.should =~ %r{1.2/disposition_codes.yml$}
83
+ subject.disposition_codes.should =~ %r{#{version}/disposition_codes.yml$}
88
84
  end
89
85
 
90
86
  it 'is of the specified version' do
91
- subject.version.should == '1.2'
87
+ subject.version.should == version
88
+ end
89
+ end
90
+
91
+ describe '1.2' do
92
+ let(:version) { '1.2' }
93
+
94
+ include_context 'version docs'
95
+
96
+ it 'has the correct path for the schema' do
97
+ subject.schema.should =~ %r{1.2/Data_Transmission_Schema_V1.2.xsd$}
92
98
  end
93
99
 
94
100
  it 'has no more specific specification_version' do
@@ -97,26 +103,44 @@ module NcsNavigator::Mdes
97
103
  end
98
104
 
99
105
  describe '2.0' do
100
- subject { SourceDocuments.get('2.0') }
106
+ let(:version) { '2.0' }
107
+
108
+ include_context 'version docs'
101
109
 
102
110
  it 'has the correct path for the schema' do
103
111
  subject.schema.should =~ %r{2.0/NCS_Transmission_Schema_2.0.01.02.xml$}
104
112
  end
105
113
 
106
- it 'has the correct path for the overrides' do
107
- subject.heuristic_overrides.should =~ %r{2.0/heuristic_overrides.yml$}
114
+ it 'has a different specification_version' do
115
+ subject.specification_version.should == '2.0.01.02'
108
116
  end
117
+ end
109
118
 
110
- it 'has the correct path for the disposition codes' do
111
- subject.disposition_codes.should =~ %r{2.0/disposition_codes.yml$}
119
+ describe '2.1' do
120
+ let(:version) { '2.1' }
121
+
122
+ include_context 'version docs'
123
+
124
+ it 'has the correct path for the schema' do
125
+ subject.schema.should =~ %r{2.1/NCS_Transmission_Schema_2.1.00.00.xsd$}
112
126
  end
113
127
 
114
- it 'is of the specified version' do
115
- subject.version.should == '2.0'
128
+ it 'has a different specification_version' do
129
+ subject.specification_version.should == '2.1.00.00'
130
+ end
131
+ end
132
+
133
+ describe '2.2' do
134
+ let(:version) { '2.2' }
135
+
136
+ include_context 'version docs'
137
+
138
+ it 'has the correct path for the schema' do
139
+ subject.schema.should =~ %r{2.2/NCS_Transmission_Schema_2.2.01.00.xsd$}
116
140
  end
117
141
 
118
142
  it 'has a different specification_version' do
119
- subject.specification_version.should == '2.0.01.02'
143
+ subject.specification_version.should == '2.2.01.00'
120
144
  end
121
145
  end
122
146