hqmf2js 1.2.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.travis.yml +2 -5
- data/Gemfile +6 -4
- data/Gemfile.lock +83 -86
- data/Rakefile +9 -5
- data/app/assets/javascripts/hqmf_util.js.coffee +98 -23
- data/app/assets/javascripts/logging_utils.js.coffee +25 -16
- data/app/assets/javascripts/patient_api_extension.js.coffee +85 -0
- data/app/assets/javascripts/specifics.js.coffee +60 -14
- data/hqmf2js.gemspec +8 -8
- data/lib/assets/javascripts/libraries/map_reduce_utils.js +130 -0
- data/lib/generator/characteristic.js.erb +28 -17
- data/lib/generator/codes_to_json.rb +5 -5
- data/lib/generator/data_criteria.js.erb +5 -5
- data/lib/generator/execution.rb +144 -0
- data/lib/generator/js.rb +46 -21
- data/lib/generator/observation_criteria.js.erb +1 -1
- data/lib/generator/patient_data.js.erb +22 -19
- data/lib/generator/population_criteria.js.erb +6 -1
- data/lib/generator/precondition.js.erb +5 -7
- data/lib/hqmf2js.rb +1 -0
- data/test/fixtures/codes/codes.json +54 -0
- data/test/fixtures/json/0495.json +1014 -0
- data/test/fixtures/json/59New.json +148 -0
- data/test/fixtures/json/data_criteria/specific_occurrence.json +27 -0
- data/test/fixtures/json/data_criteria/temporals_with_anynonnull.json +27 -0
- data/test/fixtures/patients/larry_vanderman.json +4 -4
- data/test/simplecov.rb +19 -0
- data/test/test_helper.rb +1 -1
- data/test/unit/cmd_test.rb +92 -0
- data/test/unit/codes_to_json_test.rb +32 -0
- data/test/unit/erb_context_test.rb +64 -0
- data/test/unit/hqmf_from_json_javascript_test.rb +37 -2
- data/test/unit/hqmf_javascript_test.rb +18 -0
- data/test/unit/js_object_test.rb +27 -0
- data/test/unit/library_function_test.rb +22 -21
- data/test/unit/specifics_test.rb +7 -2
- metadata +16 -121
- data/lib/tasks/cover_me.rake +0 -8
data/lib/generator/js.rb
CHANGED
@@ -166,8 +166,12 @@ module HQMF2JS
|
|
166
166
|
def initialize(doc)
|
167
167
|
@doc = doc
|
168
168
|
end
|
169
|
+
|
170
|
+
def self.map_reduce_utils
|
171
|
+
File.read(File.expand_path(File.join('..', '..', "assets",'javascripts','libraries','map_reduce_utils.js'), __FILE__))
|
172
|
+
end
|
169
173
|
|
170
|
-
def to_js(population_index=0, codes=nil)
|
174
|
+
def to_js(population_index=0, codes=nil, force_sources=nil)
|
171
175
|
population_index ||= 0
|
172
176
|
population = @doc.populations[population_index]
|
173
177
|
|
@@ -177,14 +181,23 @@ module HQMF2JS
|
|
177
181
|
oid_dictionary = "<%= oid_dictionary %>"
|
178
182
|
end
|
179
183
|
|
184
|
+
sub_ids = ('a'..'zz').to_a
|
185
|
+
sub_id = @doc.populations.size > 1 ? "'#{sub_ids[population_index]}'" : "null";
|
186
|
+
|
187
|
+
|
180
188
|
"
|
181
189
|
// #########################
|
182
190
|
// ##### DATA ELEMENTS #####
|
183
191
|
// #########################
|
184
192
|
|
193
|
+
hqmfjs.nqf_id = '#{@doc.id}';
|
194
|
+
hqmfjs.hqmf_id = '#{@doc.hqmf_id}';
|
195
|
+
hqmfjs.sub_id = #{sub_id};
|
196
|
+
if (typeof(test_id) == 'undefined') hqmfjs.test_id = null;
|
197
|
+
|
185
198
|
OidDictionary = #{oid_dictionary};
|
186
199
|
|
187
|
-
#{js_for_data_criteria()}
|
200
|
+
#{js_for_data_criteria(force_sources)}
|
188
201
|
|
189
202
|
// #########################
|
190
203
|
// ##### MEASURE LOGIC #####
|
@@ -193,7 +206,7 @@ module HQMF2JS
|
|
193
206
|
#{js_initialize_specifics(@doc.source_data_criteria)}
|
194
207
|
|
195
208
|
// INITIAL PATIENT POPULATION
|
196
|
-
#{js_for(population[HQMF::PopulationCriteria::IPP], HQMF::PopulationCriteria::IPP
|
209
|
+
#{js_for(population[HQMF::PopulationCriteria::IPP], HQMF::PopulationCriteria::IPP)}
|
197
210
|
// DENOMINATOR
|
198
211
|
#{js_for(population[HQMF::PopulationCriteria::DENOM], HQMF::PopulationCriteria::DENOM, true)}
|
199
212
|
// NUMERATOR
|
@@ -236,29 +249,34 @@ module HQMF2JS
|
|
236
249
|
end
|
237
250
|
|
238
251
|
# Generate JS for a HQMF2::DataCriteria
|
239
|
-
def js_for_data_criteria
|
240
|
-
HQMF2JS::Generator.render_template('data_criteria', {'all_criteria' => @doc.specific_occurrence_source_data_criteria.concat(@doc.all_data_criteria), 'measure_period' => @doc.measure_period})
|
252
|
+
def js_for_data_criteria(force_sources=nil)
|
253
|
+
HQMF2JS::Generator.render_template('data_criteria', {'all_criteria' => @doc.specific_occurrence_source_data_criteria(force_sources).concat(@doc.all_data_criteria), 'measure_period' => @doc.measure_period})
|
241
254
|
end
|
242
255
|
|
243
|
-
def self.library_functions(check_crosswalk=false)
|
256
|
+
def self.library_functions(check_crosswalk=false, include_underscore=true)
|
244
257
|
ctx = Sprockets::Environment.new(File.expand_path("../../..", __FILE__))
|
245
258
|
Tilt::CoffeeScriptTemplate.default_bare = true
|
246
259
|
ctx.append_path "app/assets/javascripts"
|
247
260
|
|
248
|
-
libraries = [
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
261
|
+
libraries = []
|
262
|
+
|
263
|
+
if include_underscore
|
264
|
+
libraries += ["// #########################\n// ###### Underscore.js #######\n// #######################\n",
|
265
|
+
ctx.find_asset('underscore').to_s]
|
266
|
+
end
|
267
|
+
|
268
|
+
libraries += ["// #########################\n// ###### PATIENT API #######\n// #########################\n",
|
269
|
+
HqueryPatientApi::Generator.patient_api_javascript.to_s,
|
270
|
+
"// #########################\n// ## SPECIFIC OCCURRENCES ##\n// #########################\n",
|
271
|
+
ctx.find_asset('specifics').to_s,
|
272
|
+
"// #########################\n// ### LIBRARY FUNCTIONS ####\n// #########################\n",
|
273
|
+
ctx.find_asset('hqmf_util').to_s,
|
274
|
+
"// #########################\n// ### PATIENT EXTENSION ####\n// #########################\n",
|
275
|
+
ctx.find_asset('patient_api_extension').to_s,
|
276
|
+
"// #########################\n// ## CUSTOM CALCULATIONS ###\n// #########################\n",
|
277
|
+
ctx.find_asset('custom_calculations').to_s,
|
278
|
+
"// #########################\n// ##### LOGGING UTILS ######\n// #########################\n",
|
279
|
+
ctx.find_asset('logging_utils').to_s]
|
262
280
|
|
263
281
|
# check for code set crosswalks
|
264
282
|
if (check_crosswalk)
|
@@ -270,6 +288,13 @@ module HQMF2JS
|
|
270
288
|
|
271
289
|
end
|
272
290
|
|
291
|
+
# Allow crosswalk functionality to be loaded separately from main JS libraries
|
292
|
+
def self.crosswalk_functions
|
293
|
+
ctx = Sprockets::Environment.new(File.expand_path("../../..", __FILE__))
|
294
|
+
Tilt::CoffeeScriptTemplate.default_bare = true
|
295
|
+
ctx.append_path "app/assets/javascripts"
|
296
|
+
ctx.find_asset('crosswalk').to_s
|
297
|
+
end
|
273
298
|
end
|
274
299
|
|
275
300
|
# Simple class to issue monotonically increasing integer identifiers
|
@@ -293,4 +318,4 @@ module HQMF2JS
|
|
293
318
|
include Singleton
|
294
319
|
end
|
295
320
|
end
|
296
|
-
end
|
321
|
+
end
|
@@ -1,22 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
<%-
|
6
|
-
|
7
|
-
<%-
|
8
|
-
<%-
|
9
|
-
events = events.withNegation(<%= "getCodes(\"#{criteria.negation_code_list_id}\")" if criteria.negation_code_list_id %>);
|
10
|
-
<%- else -%>
|
11
|
-
events = events.withoutNegation();
|
12
|
-
<%- end -%>
|
13
|
-
var codes = <%= js_for_code_list(criteria) %>;
|
14
|
-
var start = null;
|
15
|
-
var end = null;
|
1
|
+
<%- eventType = patient_api_method(criteria) -%>
|
2
|
+
<%- valueSetId = criteria.code_list_id -%>
|
3
|
+
<%- valueSet = criteria.inline_code_list ? js_for_code_list(criteria) : nil -%>
|
4
|
+
<%- negationValueSetId = criteria.negation_code_list_id -%>
|
5
|
+
<%- statuses = criteria.status ? "[\"#{criteria.status}\"]" : nil -%>
|
6
|
+
<%- includeEventsWithoutStatus = criteria.hard_status ? false : true -%>
|
7
|
+
<%- start = nil -%>
|
8
|
+
<%- stop = nil -%>
|
16
9
|
<%- if criteria.effective_time -%>
|
17
10
|
<%- startExp = js_for_value(criteria.effective_time.low) -%>
|
18
|
-
start =
|
19
|
-
<%-
|
20
|
-
|
11
|
+
<%- start = startExp+'.asDate()' if startExp != 'null' -%>
|
12
|
+
<%- stopExp = js_for_value(criteria.effective_time.high) -%>
|
13
|
+
<%- stop = stopExp+'.asDate()' if stopExp != 'null' -%>
|
21
14
|
<%- end -%>
|
22
|
-
|
15
|
+
var eventCriteria = {"type": "<%= eventType %>"<%- -%>
|
16
|
+
<%= ", \"statuses\": #{statuses}" if statuses %> <%- -%>
|
17
|
+
<%= ", \"includeEventsWithoutStatus\": #{includeEventsWithoutStatus}" if includeEventsWithoutStatus %> <%- -%>
|
18
|
+
<%= ", \"negated\": #{criteria.negation}" if criteria.negation %> <%- -%>
|
19
|
+
<%= ", \"negationValueSetId\": \"#{negationValueSetId}\"" if criteria.negation && negationValueSetId %> <%- -%>
|
20
|
+
<%= ", \"valueSetId\": \"#{valueSetId}\"" if valueSetId %> <%- -%>
|
21
|
+
<%= ", \"valueSet\": #{valueSet}" if valueSet %> <%- -%>
|
22
|
+
<%= ", \"start\": #{start}" if start %> <%- -%>
|
23
|
+
<%= ", \"stop\": #{stop}" if stop %> <%- -%>
|
24
|
+
<%= ", \"specificOccurrence\": \"#{criteria.source_data_criteria}\"" if criteria.specific_occurrence %>};
|
25
|
+
var events = patient.getEvents(eventCriteria);
|
@@ -1,4 +1,9 @@
|
|
1
1
|
hqmfjs.<%= type %> = function(patient, initialSpecificContext) {
|
2
|
-
|
2
|
+
population_criteria_fn = <%= js_for_precondition(criteria, 0, true) -%>;
|
3
|
+
if (typeof(population_criteria_fn) == 'function') {
|
4
|
+
return population_criteria_fn();
|
5
|
+
} else {
|
6
|
+
return population_criteria_fn;
|
7
|
+
}
|
3
8
|
};
|
4
9
|
|
@@ -1,16 +1,14 @@
|
|
1
1
|
<%- if precondition.conjunction? -%>
|
2
2
|
<%- if indent>0 -%>
|
3
|
-
<%= "\n#{' '*(indent+1)}#{conjunction_code_for(precondition)}('#{precondition.id}'," -%>
|
3
|
+
<%= "\n#{' '*(indent+1)}#{conjunction_code_for(precondition)}('#{precondition.id}', patient, initialSpecificContext," -%>
|
4
4
|
<%- else -%>
|
5
|
-
<%= "#{conjunction_code_for(precondition)}('#{precondition.id}'," -%>
|
5
|
+
<%= "#{conjunction_code_for(precondition)}('#{precondition.id}', patient, initialSpecificContext," -%>
|
6
6
|
<%- end -%>
|
7
7
|
<%- precondition.preconditions.each_with_index do |child, index| -%>
|
8
|
-
<%= "#{
|
8
|
+
<%= "#{js_for_precondition(child, indent+1, context)}" -%>
|
9
9
|
<%= "," if index < precondition.preconditions.length-1 -%>
|
10
10
|
<%- end -%>
|
11
11
|
<%= "\n#{' '*(indent+1)})" -%>
|
12
|
-
<%-
|
13
|
-
<%= " hqmfjs.#{js_name(precondition.reference)}
|
14
|
-
<%- else -%>
|
15
|
-
<%= "\n#{' '*(indent+1)}hqmfjs.#{js_name(precondition.reference)}(patient)" -%>
|
12
|
+
<%- else # !precondition.conjunction? -%>
|
13
|
+
<%= " hqmfjs.#{js_name(precondition.reference)}" -%>
|
16
14
|
<%- end -%>
|
data/lib/hqmf2js.rb
CHANGED
@@ -0,0 +1,54 @@
|
|
1
|
+
[{
|
2
|
+
"concepts": [
|
3
|
+
{
|
4
|
+
"code": "123A",
|
5
|
+
"code_system_name": "SNOMED-CT"
|
6
|
+
},
|
7
|
+
{
|
8
|
+
"code": "124B",
|
9
|
+
"code_system_name": "SNOMED-CT"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"code": "125C",
|
13
|
+
"code_system_name": "CPT"
|
14
|
+
},
|
15
|
+
{
|
16
|
+
"code": "126D",
|
17
|
+
"code_system_name": "CPT"
|
18
|
+
},
|
19
|
+
{
|
20
|
+
"code": "127E",
|
21
|
+
"code_system_name": "CPT"
|
22
|
+
}
|
23
|
+
],
|
24
|
+
"display_name": "ABD-XYZ",
|
25
|
+
"oid": "1.2.3.4.6",
|
26
|
+
"version": "20130614"
|
27
|
+
},
|
28
|
+
{
|
29
|
+
"concepts": [
|
30
|
+
{
|
31
|
+
"code": "123",
|
32
|
+
"code_system_name": "SNOMED-CT"
|
33
|
+
},
|
34
|
+
{
|
35
|
+
"code": "124",
|
36
|
+
"code_system_name": "SNOMED-CT"
|
37
|
+
},
|
38
|
+
{
|
39
|
+
"code": "125",
|
40
|
+
"code_system_name": "SNOMED-CT"
|
41
|
+
},
|
42
|
+
{
|
43
|
+
"code": "126",
|
44
|
+
"code_system_name": "ICD-9-CM"
|
45
|
+
},
|
46
|
+
{
|
47
|
+
"code": "127",
|
48
|
+
"code_system_name": "ICD-9-CM"
|
49
|
+
}
|
50
|
+
],
|
51
|
+
"display_name": "ABC-XYZ",
|
52
|
+
"oid": "1.2.3.4.5",
|
53
|
+
"version": "20130614"
|
54
|
+
}]
|