quality-measure-engine 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/qme/map/map_reduce_executor.rb +9 -1
- data/lib/qme/map/measure_calculation_job.rb +2 -0
- data/lib/qme/patient_cache.rb +4 -0
- data/lib/qme/quality_report.rb +35 -5
- data/lib/qme/version.rb +1 -1
- data/test/unit/qme/map/map_reduce_executor_test.rb +8 -0
- data/test/unit/qme/quality_report_test.rb +43 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32ed387902a54660adf12e524588392b5e329437
|
4
|
+
data.tar.gz: deaefc5e9b3fdf34cc27f3e132bc62c1019f995b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2fc390d8e5251f5e00b4517359381d17025593351099db2826dd4ba8757600df49c5700dae74a960434aa1e22137547091b6fbe974c619f8d549b1c71f450ef0
|
7
|
+
data.tar.gz: 76aea2d8f2ad3b5da238be7a83bdc39309ce607d4390683278fdab8964f085ed962c49c05d228d4fb81440b164215d6221c66df93a5d76b25eec3c7548c446d7
|
data/Gemfile.lock
CHANGED
@@ -134,7 +134,15 @@ module QME
|
|
134
134
|
if aggregate['ok'] != 1
|
135
135
|
raise RuntimeError, "Aggregation Failed"
|
136
136
|
elsif aggregate['result'].size !=1
|
137
|
-
|
137
|
+
aggregate['result'] =[{"defaults" => true,
|
138
|
+
QME::QualityReport::POPULATION => 0,
|
139
|
+
QME::QualityReport::DENOMINATOR => 0,
|
140
|
+
QME::QualityReport::NUMERATOR =>0,
|
141
|
+
QME::QualityReport::ANTINUMERATOR => 0,
|
142
|
+
QME::QualityReport::EXCLUSIONS => 0,
|
143
|
+
QME::QualityReport::EXCEPTIONS => 0,
|
144
|
+
QME::QualityReport::MSRPOPL => 0,
|
145
|
+
QME::QualityReport::CONSIDERED => 0}]
|
138
146
|
end
|
139
147
|
|
140
148
|
nqf_id = @measure_def.nqf_id || @measure_def['id']
|
@@ -40,6 +40,7 @@ module QME
|
|
40
40
|
end
|
41
41
|
@quality_report.save
|
42
42
|
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]}")
|
43
|
+
QME::QualityReport.queue_staged_rollups(@quality_report.measure_id,@quality_report.sub_id,@quality_report.effective_date)
|
43
44
|
end
|
44
45
|
end
|
45
46
|
|
@@ -58,6 +59,7 @@ module QME
|
|
58
59
|
|
59
60
|
def enqueue(job)
|
60
61
|
@quality_report.status = {"state" => "queued", "log" => ["Queued at #{Time.now}"], "job_id" => job.id}
|
62
|
+
@quality_report.save
|
61
63
|
end
|
62
64
|
|
63
65
|
|
data/lib/qme/patient_cache.rb
CHANGED
@@ -5,6 +5,10 @@
|
|
5
5
|
store_in collection: 'patient_cache'
|
6
6
|
index "value.last" => 1
|
7
7
|
index "bundle_id" => 1
|
8
|
+
index "value.measure_id" => 1
|
9
|
+
index "value.sub_id" => 1
|
10
|
+
index "value.filters.provider_performances.provider_id" => 1
|
11
|
+
index "value.medical_record_id" => 1
|
8
12
|
embeds_one :value, class_name: "QME::PatientCacheValue", inverse_of: :patient_cache
|
9
13
|
end
|
10
14
|
|
data/lib/qme/quality_report.rb
CHANGED
@@ -28,14 +28,16 @@ module QME
|
|
28
28
|
field :nqf_id, type: String
|
29
29
|
field :npi, type: String
|
30
30
|
field :calculation_time, type: Time
|
31
|
-
field :status, type: Hash, default: {"state" => "
|
31
|
+
field :status, type: Hash, default: {"state" => "unknown", "log" => []}
|
32
32
|
field :measure_id, type: String
|
33
33
|
field :sub_id, type: String
|
34
34
|
field :test_id
|
35
35
|
field :effective_date, type: Integer
|
36
36
|
field :filters, type: Hash
|
37
37
|
embeds_one :result, class_name: "QME::QualityReportResult", inverse_of: :quality_report
|
38
|
-
|
38
|
+
index "measure_id" => 1
|
39
|
+
index "sub_id" => 1
|
40
|
+
index "filters.provider_performances.provider_id" => 1
|
39
41
|
|
40
42
|
POPULATION = 'IPP'
|
41
43
|
DENOMINATOR = 'DENOM'
|
@@ -94,6 +96,14 @@ module QME
|
|
94
96
|
query.merge! @parameter_values
|
95
97
|
self.find_or_create_by(query)
|
96
98
|
end
|
99
|
+
|
100
|
+
def self.queue_staged_rollups(measure_id,sub_id,effective_date)
|
101
|
+
query = Mongoid.default_session["rollup_buffer"].find({measure_id: measure_id, sub_id: sub_id, effective_date: effective_date})
|
102
|
+
query.each do |options|
|
103
|
+
QME::QualityReport.enque_job(options,:rollup)
|
104
|
+
end
|
105
|
+
query.remove_all
|
106
|
+
end
|
97
107
|
|
98
108
|
# Determines whether the quality report has been calculated for the given
|
99
109
|
# measure and parameters
|
@@ -105,10 +115,16 @@ module QME
|
|
105
115
|
# Determines whether the patient mapping for the quality report has been
|
106
116
|
# completed
|
107
117
|
def patients_cached?
|
108
|
-
!
|
118
|
+
!QME::QualityReport.where({measure_id: self.measure_id,sub_id:self.sub_id, effective_date: self.effective_date,"status.state" => "completed" }).first.nil?
|
109
119
|
end
|
110
120
|
|
111
121
|
|
122
|
+
# Determines whether the patient mapping for the quality report has been
|
123
|
+
# queued up by another quality report or if it is currently running
|
124
|
+
def calculation_queued_or_running?
|
125
|
+
!QME::QualityReport.where({measure_id: self.measure_id,sub_id:self.sub_id, effective_date: self.effective_date }).nin("status.state" =>["unknown","stagged"]).first.nil?
|
126
|
+
end
|
127
|
+
|
112
128
|
# Kicks off a background job to calculate the measure
|
113
129
|
# @return a unique id for the measure calculation job
|
114
130
|
def calculate(parameters, asynchronous=true)
|
@@ -122,8 +138,18 @@ module QME
|
|
122
138
|
|
123
139
|
self.status["state"] = "queued"
|
124
140
|
if (asynchronous)
|
125
|
-
|
126
|
-
|
141
|
+
options[:asynchronous] = true
|
142
|
+
if patients_cached?
|
143
|
+
QME::QualityReport.enque_job(options,:rollup)
|
144
|
+
elsif calculation_queued_or_running?
|
145
|
+
self.status["state"] = "stagged"
|
146
|
+
self.save
|
147
|
+
options.merge!( {measure_id: self.measure_id, sub_id: self.sub_id, effective_date: self.effective_date })
|
148
|
+
Mongoid.default_session["rollup_buffer"].insert(options)
|
149
|
+
else
|
150
|
+
# queue the job for calculation
|
151
|
+
QME::QualityReport.enque_job(options,:calculation)
|
152
|
+
end
|
127
153
|
else
|
128
154
|
mcj = QME::MapReduce::MeasureCalculationJob.new(options)
|
129
155
|
mcj.perform
|
@@ -193,5 +219,9 @@ module QME
|
|
193
219
|
def initialize(attrs = nil, options = nil)
|
194
220
|
super(attrs, options)
|
195
221
|
end
|
222
|
+
|
223
|
+
def self.enque_job(options,queue)
|
224
|
+
Delayed::Job.enqueue(QME::MapReduce::MeasureCalculationJob.new(options), {queue: queue})
|
225
|
+
end
|
196
226
|
end
|
197
227
|
end
|
data/lib/qme/version.rb
CHANGED
@@ -76,6 +76,14 @@ class MapReduceExecutorTest < MiniTest::Unit::TestCase
|
|
76
76
|
assert_equal 3, result[QME::QualityReport::POPULATION]
|
77
77
|
assert_equal 2, result[QME::QualityReport::DENOMINATOR]
|
78
78
|
assert_equal 1, result[QME::QualityReport::NUMERATOR]
|
79
|
+
|
80
|
+
executor = QME::MapReduce::Executor.new(@quality_report.measure_id,@quality_report.sub_id, {
|
81
|
+
'effective_date' => Time.gm(2011, 1, 14).to_i})
|
82
|
+
|
83
|
+
result = executor.count_records_in_measure_groups
|
84
|
+
assert_equal 0, result[QME::QualityReport::POPULATION]
|
85
|
+
assert_equal 0, result[QME::QualityReport::DENOMINATOR]
|
86
|
+
assert_equal 0, result[QME::QualityReport::NUMERATOR]
|
79
87
|
end
|
80
88
|
|
81
89
|
def test_map_record_into_measure_groups
|
@@ -4,8 +4,9 @@ class QualityReportTest < MiniTest::Unit::TestCase
|
|
4
4
|
include QME::DatabaseAccess
|
5
5
|
|
6
6
|
def setup
|
7
|
-
|
7
|
+
load_system_js
|
8
8
|
collection_fixtures(get_db(), 'bundles')
|
9
|
+
collection_fixtures(get_db(), 'measures')
|
9
10
|
get_db()['query_cache'].drop()
|
10
11
|
get_db()['patient_cache'].drop()
|
11
12
|
get_db()['query_cache'].insert(
|
@@ -89,4 +90,45 @@ class QualityReportTest < MiniTest::Unit::TestCase
|
|
89
90
|
assert_equal :queued, status
|
90
91
|
end
|
91
92
|
|
93
|
+
def test_rollup_buffering
|
94
|
+
Delayed::Worker.delay_jobs=true
|
95
|
+
assert Delayed::Worker.delay_jobs
|
96
|
+
Delayed::Job.destroy_all
|
97
|
+
QME::QualityReport.destroy_all
|
98
|
+
Mongoid.default_session["rollup_buffer"].find({}).remove_all
|
99
|
+
qr = QME::QualityReport.find_or_create('2E679CD2-3FEC-4A75-A75A-61403E5EFEE8', nil, "effective_date" => Time.gm(2011, 9, 19).to_i)
|
100
|
+
qr2 = QME::QualityReport.find_or_create('2E679CD2-3FEC-4A75-A75A-61403E5EFEE8', nil, {"effective_date" => Time.gm(2011, 9, 19).to_i,:filters=>{"providers"=>["a"]}})
|
101
|
+
assert !qr.calculated?
|
102
|
+
assert !qr2.calculated?
|
103
|
+
assert_equal 0, Delayed::Job.count()
|
104
|
+
assert !qr.patients_cached?
|
105
|
+
assert !qr2.patients_cached?
|
106
|
+
|
107
|
+
assert !qr.calculation_queued_or_running?
|
108
|
+
assert !qr2.calculation_queued_or_running?
|
109
|
+
|
110
|
+
qr.calculate({"oid_dictionary"=>{}},true)
|
111
|
+
|
112
|
+
assert qr.calculation_queued_or_running?
|
113
|
+
assert qr2.calculation_queued_or_running?
|
114
|
+
|
115
|
+
assert_equal 0, Mongoid.default_session["rollup_buffer"].find({}).count
|
116
|
+
qr2.calculate({"oid_dictionary"=>{}},true)
|
117
|
+
assert_equal 1, Mongoid.default_session["rollup_buffer"].find({}).count
|
118
|
+
|
119
|
+
|
120
|
+
assert_equal 1, Delayed::Job.count()
|
121
|
+
job = Delayed::Job.where({}).first
|
122
|
+
assert_equal "calculation", job.queue
|
123
|
+
job.invoke_job
|
124
|
+
job.delete
|
125
|
+
|
126
|
+
assert_equal 1, Delayed::Job.count()
|
127
|
+
job = Delayed::Job.where({}).first
|
128
|
+
assert_equal "rollup", job.queue
|
129
|
+
|
130
|
+
assert_equal 0, Mongoid.default_session["rollup_buffer"].find({}).count
|
131
|
+
end
|
132
|
+
|
133
|
+
|
92
134
|
end
|
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: 3.0.
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marc Hadley
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2014-
|
15
|
+
date: 2014-04-04 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: moped
|
@@ -184,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
184
184
|
version: '0'
|
185
185
|
requirements: []
|
186
186
|
rubyforge_project:
|
187
|
-
rubygems_version: 2.
|
187
|
+
rubygems_version: 2.2.2
|
188
188
|
signing_key:
|
189
189
|
specification_version: 4
|
190
190
|
summary: This library can run JavaScript based clinical quality measures on a repository
|