quality-measure-engine 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/qme/bundle/bundle.rb +7 -4
- data/lib/qme/bundle/eh_measure_sheet.rb +22 -19
- data/lib/qme/bundle/eh_patient_importer.rb +4 -0
- data/lib/qme/bundle/importer.rb +3 -2
- data/lib/qme/map/map_reduce_executor.rb +53 -50
- data/lib/qme/map/measure_calculation_job.rb +1 -1
- data/lib/qme/quality_measure.rb +8 -0
- data/lib/qme/quality_report.rb +12 -0
- data/lib/qme/tasks/bundle.rake +6 -4
- data/lib/qme/version.rb +1 -1
- data/test/fixtures/bundles/just_measure_0002.zip +0 -0
- data/test/fixtures/eh_patient_sheets/results_matrix_eh.xlsx +0 -0
- data/test/unit/qme/bundle/eh_measure_sheet_test.rb +4 -4
- data/test/unit/qme/map/map_reduce_executor_test.rb +14 -13
- data/test/unit/qme/map/measure_calculation_job_test.rb +1 -1
- data/test/unit/qme/quality_measure_test.rb +1 -1
- data/test/unit/qme/quality_report_test.rb +9 -9
- metadata +2 -2
data/lib/qme/bundle/bundle.rb
CHANGED
@@ -31,15 +31,18 @@ module QME
|
|
31
31
|
original.split('/').last.gsub(".#{extension}", '')
|
32
32
|
end
|
33
33
|
|
34
|
-
def self.unpack_bundle_contents(zip)
|
34
|
+
def self.unpack_bundle_contents(zip, type = nil)
|
35
35
|
bundle_contents = { bundle: nil, measures: {}, patients: {}, extensions: {}, results: {} }
|
36
36
|
Zip::ZipFile.open(zip.path) do |zipfile|
|
37
37
|
zipfile.entries.each do |entry|
|
38
38
|
bundle_contents[:bundle] = zipfile.read(entry.name) if entry.name.include? "bundle"
|
39
|
-
|
40
|
-
|
39
|
+
if type.nil? || entry.name.match(Regexp.new("/#{type}/"))
|
40
|
+
bundle_contents[:measures][Bundle.entry_key(entry.name, "json")] = zipfile.read(entry.name) if entry.name.match /^measures.*\.json$/
|
41
|
+
bundle_contents[:patients][Bundle.entry_key(entry.name, "json")] = zipfile.read(entry.name) if entry.name.match /^patients.*\.json$/ # Only need to import one of the formats
|
42
|
+
bundle_contents[:results][Bundle.entry_key(entry.name,"json")] = zipfile.read(entry.name) if entry.name.match /^results.*\.json/
|
43
|
+
end
|
41
44
|
bundle_contents[:extensions][Bundle.entry_key(entry.name,"js")] = zipfile.read(entry.name) if entry.name.match /^library_functions.*\.js/
|
42
|
-
|
45
|
+
|
43
46
|
end
|
44
47
|
end
|
45
48
|
bundle_contents
|
@@ -22,16 +22,17 @@ module QME
|
|
22
22
|
qc_document.merge!(measure_ids)
|
23
23
|
extract_patients(measure_ids)
|
24
24
|
|
25
|
-
qc_document[
|
26
|
-
qc_document[
|
25
|
+
qc_document[QME::QualityReport::POPULATION] = extract_data_from_cell("C#{@population_totals_row}")
|
26
|
+
qc_document[QME::QualityReport::CONSIDERED] = @population_totals_row - 3 # header row, blank row and totals row
|
27
27
|
if cv_measure?
|
28
|
-
qc_document[
|
28
|
+
qc_document[QME::QualityReport::MSRPOPL] = extract_data_from_cell("E#{@population_totals_row}")
|
29
|
+
qc_document[QME::QualityReport::OBSERVATION] = extract_data_from_cell("F#{@population_totals_row}")
|
29
30
|
else
|
30
|
-
qc_document[
|
31
|
-
qc_document[
|
32
|
-
qc_document[
|
33
|
-
qc_document[
|
34
|
-
qc_document[
|
31
|
+
qc_document[QME::QualityReport::DENOMINATOR] = extract_data_from_cell("D#{@population_totals_row}")
|
32
|
+
qc_document[QME::QualityReport::NUMERATOR] = extract_data_from_cell("E#{@population_totals_row}")
|
33
|
+
qc_document[QME::QualityReport::ANTINUMERATOR] = qc_document[QME::QualityReport::DENOMINATOR] - qc_document[QME::QualityReport::NUMERATOR]
|
34
|
+
qc_document[QME::QualityReport::EXCLUSIONS] = extract_data_from_cell("F#{@population_totals_row}")
|
35
|
+
qc_document[QME::QualityReport::EXCEPTIONS] = extract_data_from_cell("G#{@population_totals_row}")
|
35
36
|
end
|
36
37
|
|
37
38
|
qc_document['test_id'] = nil
|
@@ -60,16 +61,17 @@ module QME
|
|
60
61
|
|
61
62
|
def extract_measure_info
|
62
63
|
measure_info = {}
|
63
|
-
measure_info[
|
64
|
+
measure_info[QME::QualityReport::POPULATION] = extract_data_from_cell('I5')
|
64
65
|
if cv_measure?
|
65
|
-
measure_info[
|
66
|
-
measure_info[
|
66
|
+
measure_info[QME::QualityReport::MSRPOPL] = extract_data_from_cell('I10')
|
67
|
+
measure_info[QME::QualityReport::OBSERVATION] = extract_data_from_cell('I11') if extract_data_from_cell('I11').present?
|
68
|
+
measure_info['stratification'] = extract_data_from_cell('I12') if extract_data_from_cell('I12').present?
|
67
69
|
else
|
68
70
|
measure_info['DENOM'] = extract_data_from_cell('I6')
|
69
71
|
measure_info['NUMER'] = extract_data_from_cell('I7')
|
70
72
|
measure_info['DENEXCEP'] = extract_data_from_cell('I8') if extract_data_from_cell('I8').present?
|
71
73
|
measure_info['DENEX'] = extract_data_from_cell('I9') if extract_data_from_cell('I9').present?
|
72
|
-
measure_info['stratification'] = extract_data_from_cell('
|
74
|
+
measure_info['stratification'] = extract_data_from_cell('I12') if extract_data_from_cell('I12').present?
|
73
75
|
end
|
74
76
|
|
75
77
|
measure_info
|
@@ -81,15 +83,16 @@ module QME
|
|
81
83
|
'ethnicity', 'languages')
|
82
84
|
patient_document['medical_record_id'] = medical_record_number
|
83
85
|
patient_document['patient_id'] = record['_id'].to_s
|
84
|
-
patient_document[
|
86
|
+
patient_document[QME::QualityReport::POPULATION] = extract_data_from_cell("C#{row}") || 0
|
85
87
|
if cv_measure?
|
86
|
-
patient_document[
|
88
|
+
patient_document[QME::QualityReport::MSRPOPL] = extract_data_from_cell("E#{row}") || 0
|
89
|
+
patient_document['values'] = [extract_data_from_cell("F#{row}")]
|
87
90
|
else
|
88
|
-
patient_document[
|
89
|
-
patient_document[
|
90
|
-
patient_document[
|
91
|
-
patient_document[
|
92
|
-
patient_document[
|
91
|
+
patient_document[QME::QualityReport::DENOMINATOR] = extract_data_from_cell("D#{row}") || 0
|
92
|
+
patient_document[QME::QualityReport::NUMERATOR] = extract_data_from_cell("E#{row}") || 0
|
93
|
+
patient_document[QME::QualityReport::EXCLUSIONS] = extract_data_from_cell("F#{row}") || 0
|
94
|
+
patient_document[QME::QualityReport::EXCEPTIONS] = extract_data_from_cell("G#{row}") || 0
|
95
|
+
patient_document[QME::QualityReport::ANTINUMERATOR] = patient_document[QME::QualityReport::DENOMINATOR] - patient_document[QME::QualityReport::NUMERATOR]
|
93
96
|
|
94
97
|
end
|
95
98
|
patient_document['test_id'] = nil
|
@@ -6,8 +6,12 @@ module QME
|
|
6
6
|
ms = EHMeasureSheet.new(db, worksheet, effective_date)
|
7
7
|
ms.parse
|
8
8
|
qc_document = ms.query_cache_document
|
9
|
+
db['query_cache'].find({measure_id: qc_document['measure_id'], sub_id: qc_document['sub_id']}).remove
|
10
|
+
db.command(getLastError: 1)
|
9
11
|
db['query_cache'].insert(qc_document)
|
10
12
|
ms.patient_cache_documents.each do |pcd|
|
13
|
+
db['patient_cache'].find({'value.measure_id'=>pcd['value']['measure_id'], 'value.sub_id'=>pcd['value']['sub_id'],'value.medical_record_id'=>pcd['value']['medical_record_id']}).remove
|
14
|
+
db.command(getLastError: 1)
|
11
15
|
db['patient_cache'].insert(pcd)
|
12
16
|
end
|
13
17
|
ms.patient_updates.each do |patient_update|
|
data/lib/qme/bundle/importer.rb
CHANGED
@@ -13,12 +13,13 @@ module QME
|
|
13
13
|
# Import a quality bundle into the database. This includes metadata, measures, test patients, supporting JS libraries, and expected results.
|
14
14
|
#
|
15
15
|
# @param [File] zip The bundle zip file.
|
16
|
+
# @param [String] Type of measures to import, either 'ep', 'eh' or nil for all
|
16
17
|
# @param [Boolean] keep_existing If true, delete all current collections related to patients and measures.
|
17
|
-
def import(zip,
|
18
|
+
def import(zip, delete_existing, type=nil)
|
18
19
|
Bundle.drop_collections(@db) if delete_existing
|
19
20
|
|
20
21
|
# Unpack content from the bundle.
|
21
|
-
bundle_contents = QME::Bundle.unpack_bundle_contents(zip)
|
22
|
+
bundle_contents = QME::Bundle.unpack_bundle_contents(zip, type)
|
22
23
|
|
23
24
|
# Store all JS libraries.
|
24
25
|
bundle_contents[:extensions].each do |key, contents|
|
@@ -20,32 +20,66 @@ module QME
|
|
20
20
|
determine_connection_information()
|
21
21
|
end
|
22
22
|
|
23
|
+
def build_query
|
24
|
+
pipeline = []
|
25
|
+
|
26
|
+
filters = @parameter_values['filters']
|
27
|
+
|
28
|
+
|
29
|
+
match = {'value.measure_id' => @measure_id,
|
30
|
+
'value.sub_id' => @sub_id,
|
31
|
+
'value.effective_date' => @parameter_values['effective_date'],
|
32
|
+
'value.test_id' => @parameter_values['test_id'],
|
33
|
+
'value.manual_exclusion' => {'$in' => [nil, false]}}
|
34
|
+
|
35
|
+
if(filters)
|
36
|
+
if (filters['races'] && filters['races'].size > 0)
|
37
|
+
match['value.race.code'] = {'$in' => filters['races']}
|
38
|
+
end
|
39
|
+
if (filters['ethnicities'] && filters['ethnicities'].size > 0)
|
40
|
+
match['value.ethnicity.code'] = {'$in' => filters['ethnicities']}
|
41
|
+
end
|
42
|
+
if (filters['genders'] && filters['genders'].size > 0)
|
43
|
+
match['value.gender'] = {'$in' => filters['genders']}
|
44
|
+
end
|
45
|
+
if (filters['providers'] && filters['providers'].size > 0)
|
46
|
+
providers = filters['providers'].map { |pv| {'providers' => Moped::BSON::ObjectId(pv) } }
|
47
|
+
pipeline.concat [{'$project' => {'value' => 1, 'providers' => "$value.provider_performances.provider_id"}},
|
48
|
+
{'$unwind' => '$providers'},
|
49
|
+
{'$match' => {'$or' => providers}},
|
50
|
+
{'$group' => {"_id" => "$_id", "value" => {"$first" => "$value"}}}]
|
51
|
+
end
|
52
|
+
if (filters['languages'] && filters['languages'].size > 0)
|
53
|
+
languages = filters['languages'].map { |l| {'languages' => l } }
|
54
|
+
pipeline.concat [{'$project' => {'value' => 1, 'languages' => "$value.languages"}},
|
55
|
+
{'$unwind' => "$languages"},
|
56
|
+
{'$project' => {'value' => 1, 'languages' => {'$substr' => ['$languages', 0, 2]}}},
|
57
|
+
{'$match' => {'$or' => languages}},
|
58
|
+
{'$group' => {"_id" => "$_id", "value" => {"$first" => "$value"}}}]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
pipeline.unshift({'$match' => match})
|
63
|
+
|
64
|
+
pipeline
|
65
|
+
end
|
66
|
+
|
23
67
|
# Examines the patient_cache collection and generates a total of all groups
|
24
68
|
# for the measure. The totals are placed in a document in the query_cache
|
25
69
|
# collection.
|
26
70
|
# @return [Hash] measure groups (like numerator) as keys, counts as values
|
27
71
|
def count_records_in_measure_groups
|
28
|
-
pipeline =
|
29
|
-
base_query = {'value.measure_id' => @measure_id, 'value.sub_id' => @sub_id,
|
30
|
-
'value.effective_date' => @parameter_values['effective_date'],
|
31
|
-
'value.test_id' => @parameter_values['test_id']}
|
32
|
-
|
33
|
-
base_query.merge!(filter_parameters)
|
34
|
-
|
35
|
-
query = base_query.clone
|
36
|
-
|
37
|
-
query.merge!({'value.manual_exclusion' => {'$in' => [nil, false]}})
|
72
|
+
pipeline = build_query
|
38
73
|
|
39
|
-
pipeline << {'$match' => query}
|
40
74
|
pipeline << {'$group' => {
|
41
75
|
"_id" => "$value.measure_id", # we don't really need this, but Mongo requires that we group
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
76
|
+
QME::QualityReport::POPULATION => {"$sum" => "$value.#{QME::QualityReport::POPULATION}"},
|
77
|
+
QME::QualityReport::DENOMINATOR => {"$sum" => "$value.#{QME::QualityReport::DENOMINATOR}"},
|
78
|
+
QME::QualityReport::NUMERATOR => {"$sum" => "$value.#{QME::QualityReport::NUMERATOR}"},
|
79
|
+
QME::QualityReport::ANTINUMERATOR => {"$sum" => "$value.#{QME::QualityReport::ANTINUMERATOR}"},
|
80
|
+
QME::QualityReport::EXCLUSIONS => {"$sum" => "$value.#{QME::QualityReport::EXCLUSIONS}"},
|
81
|
+
QME::QualityReport::EXCEPTIONS => {"$sum" => "$value.#{QME::QualityReport::EXCEPTIONS}"},
|
82
|
+
QME::QualityReport::CONSIDERED => {"$sum" => 1}
|
49
83
|
}}
|
50
84
|
|
51
85
|
aggregate = get_db.command(:aggregate => 'patient_cache', :pipeline => pipeline)
|
@@ -62,7 +96,7 @@ module QME
|
|
62
96
|
|
63
97
|
result.merge!(aggregate['result'].first)
|
64
98
|
result.reject! {|k, v| k == '_id'} # get rid of the group id the Mongo forced us to use
|
65
|
-
result['exclusions'] += get_db['patient_cache'].find(base_query.merge({'value.manual_exclusion'=>true})).count
|
99
|
+
# result['exclusions'] += get_db['patient_cache'].find(base_query.merge({'value.manual_exclusion'=>true})).count
|
66
100
|
result.merge!(execution_time: (Time.now.to_i - @parameter_values['start_time'].to_i)) if @parameter_values['start_time']
|
67
101
|
get_db()["query_cache"].insert(result)
|
68
102
|
get_db().command({:getLastError => 1}) # make sure last insert finished before we continue
|
@@ -123,37 +157,6 @@ module QME
|
|
123
157
|
get_db()['patient_cache'].find({'value.measure_id'=>@measure_id, 'value.sub_id'=>@sub_id, 'value.medical_record_id'=>{'$in'=>exclusions} })
|
124
158
|
.update_all({'$set'=>{'value.manual_exclusion'=>true}})
|
125
159
|
end
|
126
|
-
|
127
|
-
def filter_parameters
|
128
|
-
results = {}
|
129
|
-
conditions = []
|
130
|
-
if(filters = @parameter_values['filters'])
|
131
|
-
if (filters['providers'] && filters['providers'].size > 0)
|
132
|
-
providers = filters['providers'].map {|provider_id| Moped::BSON::ObjectId(provider_id) if (provider_id and provider_id != 'null') }
|
133
|
-
# provider_performances have already been filtered by start and end date in map_reduce_builder as part of the finalize
|
134
|
-
conditions << {'value.provider_performances.provider_id' => {'$in' => providers}}
|
135
|
-
end
|
136
|
-
if (filters['races'] && filters['races'].size > 0)
|
137
|
-
conditions << {'value.race.code' => {'$in' => filters['races']}}
|
138
|
-
end
|
139
|
-
if (filters['ethnicities'] && filters['ethnicities'].size > 0)
|
140
|
-
conditions << {'value.ethnicity.code' => {'$in' => filters['ethnicities']}}
|
141
|
-
end
|
142
|
-
if (filters['genders'] && filters['genders'].size > 0)
|
143
|
-
conditions << {'value.gender' => {'$in' => filters['genders']}}
|
144
|
-
end
|
145
|
-
if (filters['languages'] && filters['languages'].size > 0)
|
146
|
-
languages = filters['languages'].clone
|
147
|
-
has_unspecified = languages.delete('null')
|
148
|
-
or_clauses = []
|
149
|
-
or_clauses << {'value.languages'=>{'$regex'=>Regexp.new("(#{languages.join("|")})-..")}} if languages.length > 0
|
150
|
-
or_clauses << {'value.languages'=>nil} if (has_unspecified)
|
151
|
-
conditions << {'$or'=>or_clauses}
|
152
|
-
end
|
153
|
-
end
|
154
|
-
results.merge!({'$and'=>conditions}) if conditions.length > 0
|
155
|
-
results
|
156
|
-
end
|
157
160
|
end
|
158
161
|
end
|
159
162
|
end
|
@@ -33,7 +33,7 @@ module QME
|
|
33
33
|
|
34
34
|
tick('Calculating group totals')
|
35
35
|
result = map.count_records_in_measure_groups
|
36
|
-
completed("#{@measure_id}#{@sub_id}: p#{result[
|
36
|
+
completed("#{@measure_id}#{@sub_id}: p#{result[QME::QualityReport::POPULATION]}, d#{result[QME::QualityReport::DENOMINATOR]}, n#{result[QME::QualityReport::NUMERATOR]}, excl#{result[QME::QualityReport::EXCLUSIONS]}, excep#{result[QME::QualityReport::EXCEPTIONS]}")
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
data/lib/qme/quality_measure.rb
CHANGED
@@ -21,6 +21,14 @@ module QME
|
|
21
21
|
def self.get_measures(measure_ids)
|
22
22
|
get_db()['measures'].find('id' => {"$in" => measure_ids})
|
23
23
|
end
|
24
|
+
|
25
|
+
def self.get(measure_id, sub_id)
|
26
|
+
get_db()['measures'].find('id' => measure_id, 'sub_id' => sub_id)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.sub_measures(measure_id)
|
30
|
+
get_db()['measures'].find('id' => measure_id)
|
31
|
+
end
|
24
32
|
|
25
33
|
# Creates a new QualityMeasure
|
26
34
|
# @param [String] measure_id value of the measure's id field
|
data/lib/qme/quality_report.rb
CHANGED
@@ -1,11 +1,23 @@
|
|
1
1
|
module QME
|
2
|
+
|
2
3
|
# A class that allows you to create and obtain the results of running a
|
3
4
|
# quality measure against a set of patient records.
|
4
5
|
class QualityReport
|
6
|
+
|
5
7
|
include DatabaseAccess
|
6
8
|
extend DatabaseAccess
|
7
9
|
determine_connection_information
|
8
10
|
|
11
|
+
POPULATION = 'IPP'
|
12
|
+
DENOMINATOR = 'DENOM'
|
13
|
+
NUMERATOR = 'NUMER'
|
14
|
+
EXCLUSIONS = 'DENEX'
|
15
|
+
EXCEPTIONS = 'DENEXCEP'
|
16
|
+
MSRPOPL = 'MSRPOPL'
|
17
|
+
OBSERVATION = 'OBSERV'
|
18
|
+
ANTINUMERATOR = 'antinumerator'
|
19
|
+
CONSIDERED = 'considered'
|
20
|
+
|
9
21
|
# Gets rid of all calculated QualityReports by dropping the patient_cache
|
10
22
|
# and query_cache collections
|
11
23
|
def self.destroy_all
|
data/lib/qme/tasks/bundle.rake
CHANGED
@@ -4,19 +4,19 @@ db_name = ENV['DB_NAME'] || 'test'
|
|
4
4
|
|
5
5
|
namespace :bundle do
|
6
6
|
desc 'Import a quality bundle into the database.'
|
7
|
-
task :import, [:bundle_path, :
|
7
|
+
task :import, [:bundle_path, :delete_existing, :type] => [:environment] do |task, args|
|
8
8
|
raise "The path to the measures zip file must be specified" unless args.bundle_path
|
9
9
|
|
10
10
|
bundle = File.open(args.bundle_path)
|
11
11
|
importer = QME::Bundle::Importer.new(db_name)
|
12
|
-
bundle_contents = importer.import(bundle,
|
12
|
+
bundle_contents = importer.import(bundle, args.delete_existing == "true", args.type)
|
13
13
|
|
14
14
|
puts "Successfully imported bundle at: #{args.bundle_path}"
|
15
15
|
puts "\t Imported into environment: #{Rails.env.upcase}" if defined? Rails
|
16
|
+
puts "\t Loaded #{args.type || "all"} measures"
|
16
17
|
puts "\t Measures Loaded: #{bundle_contents[:measures].count}"
|
17
18
|
puts "\t Test Patients Loaded: #{bundle_contents[:patients].count}"
|
18
19
|
puts "\t Extensions Loaded: #{bundle_contents[:extensions].count}"
|
19
|
-
|
20
20
|
end
|
21
21
|
|
22
22
|
# this task is most likely temporary. Once Bonnie can handle both EP and EH measures together, this would no longer be required.
|
@@ -68,11 +68,13 @@ namespace :bundle do
|
|
68
68
|
['measures','patients','extensions'].each do |key|
|
69
69
|
json_out[key] = (json_one[key] + json_two[key]).uniq
|
70
70
|
end
|
71
|
+
|
72
|
+
version = json_out['version']
|
71
73
|
|
72
74
|
File.open(File.join(tmpdir,'output','bundle.json'), 'w') {|f| f.write(JSON.pretty_generate(json_out)) }
|
73
75
|
date_string = Time.now.strftime("%Y-%m-%d")
|
74
76
|
|
75
|
-
out_zip = File.join('tmp','bundles',"bundle-merged-#{date_string}.zip")
|
77
|
+
out_zip = File.join('tmp','bundles',"bundle-merged-#{date_string}-#{version}.zip")
|
76
78
|
FileUtils.remove_entry_secure out_zip if File.exists?(out_zip)
|
77
79
|
Zip::ZipFile.open(out_zip, 'w') do |zipfile|
|
78
80
|
path = File.join(tmpdir,'output')
|
data/lib/qme/version.rb
CHANGED
Binary file
|
Binary file
|
@@ -21,16 +21,16 @@ class EHMeasureSheetTest < MiniTest::Unit::TestCase
|
|
21
21
|
@ms.parse
|
22
22
|
qcd = @ms.query_cache_document
|
23
23
|
assert_equal '0142', qcd['nqf_id']
|
24
|
-
assert_equal 4, qcd[
|
24
|
+
assert_equal 4, qcd[QME::QualityReport::POPULATION]
|
25
25
|
assert_equal 12345000, qcd['effective_date']
|
26
26
|
end
|
27
27
|
|
28
28
|
def test_patient_cache_documents
|
29
29
|
@ms.parse
|
30
30
|
pcd = @ms.patient_cache_documents.first
|
31
|
-
assert_equal 1, pcd['value'][
|
32
|
-
assert_equal 0, pcd['value'][
|
33
|
-
assert_equal 1, pcd['value'][
|
31
|
+
assert_equal 1, pcd['value'][QME::QualityReport::POPULATION]
|
32
|
+
assert_equal 0, pcd['value'][QME::QualityReport::NUMERATOR]
|
33
|
+
assert_equal 1, pcd['value'][QME::QualityReport::ANTINUMERATOR]
|
34
34
|
assert_equal '1234', pcd['value']['medical_record_id']
|
35
35
|
assert_equal 12345000, pcd['value']['effective_date']
|
36
36
|
end
|
@@ -5,7 +5,7 @@ class MapReduceExecutorTest < MiniTest::Unit::TestCase
|
|
5
5
|
|
6
6
|
def setup
|
7
7
|
importer = QME::Bundle::Importer.new
|
8
|
-
importer.import(File.new('test/fixtures/bundles/just_measure_0002.zip'), true)
|
8
|
+
importer.import(File.new('test/fixtures/bundles/just_measure_0002.zip'), true, nil)
|
9
9
|
|
10
10
|
collection_fixtures(get_db(), 'records', '_id')
|
11
11
|
end
|
@@ -13,13 +13,14 @@ class MapReduceExecutorTest < MiniTest::Unit::TestCase
|
|
13
13
|
def test_map_records_into_measure_groups
|
14
14
|
executor = QME::MapReduce::Executor.new("2E679CD2-3FEC-4A75-A75A-61403E5EFEE8", nil,
|
15
15
|
'effective_date' => Time.gm(2011, 1, 15).to_i)
|
16
|
+
|
16
17
|
executor.map_records_into_measure_groups
|
17
18
|
|
18
19
|
assert_equal 4, get_db['patient_cache'].find().count
|
19
|
-
assert_equal 3, get_db['patient_cache'].find(
|
20
|
-
assert_equal 1, get_db['patient_cache'].find(
|
21
|
-
assert_equal 2, get_db['patient_cache'].find(
|
22
|
-
assert_equal 1, get_db['patient_cache'].find(
|
20
|
+
assert_equal 3, get_db['patient_cache'].find("value.#{QME::QualityReport::POPULATION}" => 1).count
|
21
|
+
assert_equal 1, get_db['patient_cache'].find("value.#{QME::QualityReport::POPULATION}" => 0).count
|
22
|
+
assert_equal 2, get_db['patient_cache'].find("value.#{QME::QualityReport::DENOMINATOR}" => 1).count
|
23
|
+
assert_equal 1, get_db['patient_cache'].find("value.#{QME::QualityReport::NUMERATOR}" => 1).count
|
23
24
|
end
|
24
25
|
|
25
26
|
def test_count_records_in_measure_groups
|
@@ -29,9 +30,9 @@ class MapReduceExecutorTest < MiniTest::Unit::TestCase
|
|
29
30
|
executor.count_records_in_measure_groups
|
30
31
|
assert_equal 1, get_db['query_cache'].find().count
|
31
32
|
doc = get_db['query_cache'].find().first
|
32
|
-
assert_equal 3, doc[
|
33
|
-
assert_equal 2, doc[
|
34
|
-
assert_equal 1, doc[
|
33
|
+
assert_equal 3, doc[QME::QualityReport::POPULATION]
|
34
|
+
assert_equal 2, doc[QME::QualityReport::DENOMINATOR]
|
35
|
+
assert_equal 1, doc[QME::QualityReport::NUMERATOR]
|
35
36
|
end
|
36
37
|
|
37
38
|
def test_map_record_into_measure_groups
|
@@ -40,10 +41,10 @@ class MapReduceExecutorTest < MiniTest::Unit::TestCase
|
|
40
41
|
executor.map_record_into_measure_groups("12345")
|
41
42
|
|
42
43
|
assert_equal 1, get_db['patient_cache'].find().count
|
43
|
-
assert_equal 1, get_db['patient_cache'].find(
|
44
|
-
assert_equal 0, get_db['patient_cache'].find(
|
45
|
-
assert_equal 1, get_db['patient_cache'].find(
|
46
|
-
assert_equal 1, get_db['patient_cache'].find(
|
44
|
+
assert_equal 1, get_db['patient_cache'].find("value.#{QME::QualityReport::POPULATION}" => 1).count
|
45
|
+
assert_equal 0, get_db['patient_cache'].find("value.#{QME::QualityReport::POPULATION}" => 0).count
|
46
|
+
assert_equal 1, get_db['patient_cache'].find("value.#{QME::QualityReport::DENOMINATOR}" => 1).count
|
47
|
+
assert_equal 1, get_db['patient_cache'].find("value.#{QME::QualityReport::NUMERATOR}" => 1).count
|
47
48
|
end
|
48
49
|
|
49
50
|
def test_get_patient_result
|
@@ -51,6 +52,6 @@ class MapReduceExecutorTest < MiniTest::Unit::TestCase
|
|
51
52
|
'effective_date' => Time.gm(2011, 1, 15).to_i)
|
52
53
|
result = executor.get_patient_result("12345")
|
53
54
|
assert_equal 0, get_db['patient_cache'].find().count
|
54
|
-
assert result[
|
55
|
+
assert result[QME::QualityReport::NUMERATOR]
|
55
56
|
end
|
56
57
|
end
|
@@ -5,7 +5,7 @@ class MapCalculationJobTest < MiniTest::Unit::TestCase
|
|
5
5
|
|
6
6
|
def setup
|
7
7
|
importer = QME::Bundle::Importer.new
|
8
|
-
importer.import(File.new('test/fixtures/bundles/just_measure_0002.zip'),
|
8
|
+
importer.import(File.new('test/fixtures/bundles/just_measure_0002.zip'), true, nil)
|
9
9
|
|
10
10
|
collection_fixtures(get_db(), 'records', '_id')
|
11
11
|
|
@@ -3,7 +3,7 @@ require 'test_helper'
|
|
3
3
|
class QualityMeasureTest < MiniTest::Unit::TestCase
|
4
4
|
def setup
|
5
5
|
importer = QME::Bundle::Importer.new
|
6
|
-
importer.import(File.new('test/fixtures/bundles/just_measure_0002.zip'), true)
|
6
|
+
importer.import(File.new('test/fixtures/bundles/just_measure_0002.zip'), true,nil)
|
7
7
|
end
|
8
8
|
|
9
9
|
def test_getting_all_measures
|
@@ -10,18 +10,18 @@ class QualityReportTest < MiniTest::Unit::TestCase
|
|
10
10
|
"measure_id" => "test2",
|
11
11
|
"sub_id" => "b",
|
12
12
|
"initialPopulation" => 4,
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
QME::QualityReport::NUMERATOR => 1,
|
14
|
+
QME::QualityReport::DENOMINATOR => 2,
|
15
|
+
QME::QualityReport::EXCLUSIONS => 1,
|
16
16
|
"effective_date" => Time.gm(2010, 9, 19).to_i
|
17
17
|
)
|
18
18
|
get_db()['patient_cache'].insert(
|
19
19
|
"value" => {
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
QME::QualityReport::POPULATION => 0,
|
21
|
+
QME::QualityReport::DENOMINATOR => 0,
|
22
|
+
QME::QualityReport::NUMERATOR => 0,
|
23
|
+
QME::QualityReport::EXCLUSIONS => 0,
|
24
|
+
QME::QualityReport::ANTINUMERATOR => 0,
|
25
25
|
"medical_record_id" => "0616911582",
|
26
26
|
"first" => "Mary",
|
27
27
|
"last" => "Edwards",
|
@@ -57,7 +57,7 @@ class QualityReportTest < MiniTest::Unit::TestCase
|
|
57
57
|
qr = QME::QualityReport.new('test2', 'b', "effective_date" => Time.gm(2010, 9, 19).to_i)
|
58
58
|
result = qr.result
|
59
59
|
|
60
|
-
assert_equal 1, result[
|
60
|
+
assert_equal 1, result[QME::QualityReport::NUMERATOR]
|
61
61
|
end
|
62
62
|
|
63
63
|
def test_destroy_all
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quality-measure-engine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2012-
|
15
|
+
date: 2012-12-19 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: moped
|