quality-measure-engine 3.0.0 → 3.0.1
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.
- 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
|