quality-measure-engine 1.1.5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +12 -0
- data/.travis.yml +16 -0
- data/Gemfile +5 -21
- data/Gemfile.lock +126 -0
- data/LICENSE.txt +13 -0
- data/README.md +23 -44
- data/Rakefile +6 -29
- data/lib/qme/bundle/bundle.rb +34 -0
- data/lib/qme/bundle/importer.rb +69 -0
- data/lib/qme/database_access.rb +7 -11
- data/lib/qme/map/map_reduce_builder.rb +4 -1
- data/lib/qme/map/map_reduce_executor.rb +55 -43
- data/lib/qme/map/measure_calculation_job.rb +24 -23
- data/lib/qme/quality_measure.rb +5 -5
- data/lib/qme/quality_report.rb +37 -19
- data/lib/qme/railtie.rb +7 -0
- data/lib/qme/tasks/bundle.rake +14 -0
- data/lib/qme/version.rb +3 -0
- data/lib/quality-measure-engine.rb +13 -25
- data/quality-measure-engine.gemspec +28 -0
- data/test/fixtures/bundles/just_measure_0002.zip +0 -0
- data/test/fixtures/delayed_backend_mongoid_jobs/queued_job.json +9 -0
- data/test/fixtures/measures/measure_metadata.json +52 -0
- data/test/fixtures/records/barry_berry.json +471 -0
- data/test/fixtures/records/billy_jones_ipp.json +78 -0
- data/test/fixtures/records/jane_jones_numerator.json +120 -0
- data/test/fixtures/records/jill_jones_denominator.json +78 -0
- data/test/simplecov_setup.rb +18 -0
- data/test/test_helper.rb +26 -0
- data/test/unit/qme/map/map_reduce_builder_test.rb +38 -0
- data/test/unit/qme/map/map_reduce_executor_test.rb +56 -0
- data/test/unit/qme/map/measure_calculation_job_test.rb +22 -0
- data/test/unit/qme/quality_measure_test.rb +14 -0
- data/{spec/qme/quality_report_spec.rb → test/unit/qme/quality_report_test.rb} +32 -20
- metadata +91 -115
- data/VERSION +0 -1
- data/js/map_reduce_utils.js +0 -173
- data/js/underscore_min.js +0 -25
- data/lib/qme/ext/record.rb +0 -43
- data/lib/qme/importer/entry.rb +0 -126
- data/lib/qme/importer/generic_importer.rb +0 -117
- data/lib/qme/importer/measure_properties_generator.rb +0 -39
- data/lib/qme/importer/property_matcher.rb +0 -110
- data/lib/qme/measure/database_loader.rb +0 -83
- data/lib/qme/measure/measure_loader.rb +0 -174
- data/lib/qme/measure/properties_builder.rb +0 -184
- data/lib/qme/measure/properties_converter.rb +0 -27
- data/lib/qme/randomizer/patient_randomization_job.rb +0 -47
- data/lib/qme/randomizer/patient_randomizer.rb +0 -250
- data/lib/qme/randomizer/random_patient_creator.rb +0 -47
- data/lib/qme_test.rb +0 -13
- data/lib/tasks/fixtures.rake +0 -91
- data/lib/tasks/measure.rake +0 -110
- data/lib/tasks/mongo.rake +0 -68
- data/lib/tasks/patient_random.rake +0 -45
- data/spec/qme/bundle_spec.rb +0 -37
- data/spec/qme/importer/generic_importer_spec.rb +0 -73
- data/spec/qme/importer/measure_properties_generator_spec.rb +0 -15
- data/spec/qme/importer/property_matcher_spec.rb +0 -174
- data/spec/qme/map/map_reduce_builder_spec.rb +0 -38
- data/spec/qme/map/measures_spec.rb +0 -38
- data/spec/qme/map/patient_mapper_spec.rb +0 -11
- data/spec/qme/measure_loader_spec.rb +0 -12
- data/spec/qme/properties_builder_spec.rb +0 -61
- data/spec/spec_helper.rb +0 -120
- data/spec/validate_measures_spec.rb +0 -21
@@ -85,12 +85,15 @@ module QME
|
|
85
85
|
"function (key, value) {
|
86
86
|
var patient = value;
|
87
87
|
patient.measure_id = \"#{@measure_def['id']}\";\n"
|
88
|
-
if @params['test_id'] && @params['test_id'].class==BSON::ObjectId
|
88
|
+
if @params['test_id'] && @params['test_id'].class==Moped::BSON::ObjectId
|
89
89
|
reduce += " patient.test_id = new ObjectId(\"#{@params['test_id']}\");\n"
|
90
90
|
end
|
91
91
|
if @measure_def['sub_id']
|
92
92
|
reduce += " patient.sub_id = \"#{@measure_def['sub_id']}\";\n"
|
93
93
|
end
|
94
|
+
if @measure_def['nqf_id']
|
95
|
+
reduce += " patient.nqf_id = \"#{@measure_def['nqf_id']}\";\n"
|
96
|
+
end
|
94
97
|
|
95
98
|
reduce += "patient.effective_date = #{@params['effective_date']};
|
96
99
|
if (patient.provider_performances) {
|
@@ -16,7 +16,8 @@ module QME
|
|
16
16
|
@measure_id = measure_id
|
17
17
|
@sub_id = sub_id
|
18
18
|
@parameter_values = parameter_values
|
19
|
-
|
19
|
+
@measure_def = QualityMeasure.new(@measure_id, @sub_id).definition
|
20
|
+
determine_connection_information()
|
20
21
|
end
|
21
22
|
|
22
23
|
# Examines the patient_cache collection and generates a total of all groups
|
@@ -24,7 +25,7 @@ module QME
|
|
24
25
|
# collection.
|
25
26
|
# @return [Hash] measure groups (like numerator) as keys, counts as values
|
26
27
|
def count_records_in_measure_groups
|
27
|
-
|
28
|
+
pipeline = []
|
28
29
|
base_query = {'value.measure_id' => @measure_id, 'value.sub_id' => @sub_id,
|
29
30
|
'value.effective_date' => @parameter_values['effective_date'],
|
30
31
|
'value.test_id' => @parameter_values['test_id']}
|
@@ -34,25 +35,37 @@ module QME
|
|
34
35
|
query = base_query.clone
|
35
36
|
|
36
37
|
query.merge!({'value.manual_exclusion' => {'$in' => [nil, false]}})
|
38
|
+
|
39
|
+
pipeline << {'$match' => query}
|
40
|
+
pipeline << {'$group' => {
|
41
|
+
"_id" => "$value.measure_id", # we don't really need this, but Mongo requires that we group
|
42
|
+
"population" => {"$sum" => "$value.population"},
|
43
|
+
"denominator" => {"$sum" => "$value.denominator"},
|
44
|
+
"numerator" => {"$sum" => "$value.numerator"},
|
45
|
+
"antinumerator" => {"$sum" => "$value.antinumerator"},
|
46
|
+
"exclusions" => {"$sum" => "$value.exclusions"},
|
47
|
+
"denexcep" => {"$sum" => "$value.denexcep"},
|
48
|
+
"considered" => {"$sum" => 1}
|
49
|
+
}}
|
37
50
|
|
38
|
-
|
51
|
+
aggregate = get_db.command(:aggregate => 'patient_cache', :pipeline => pipeline)
|
52
|
+
if aggregate['ok'] != 1
|
53
|
+
raise RuntimeError, "Aggregation Failed"
|
54
|
+
elsif aggregate['result'].size !=1
|
55
|
+
raise RuntimeError, "Expected one group from patient_cache aggregation, got #{aggregate['result'].size}"
|
56
|
+
end
|
57
|
+
|
58
|
+
nqf_id = @measure_def['nqf_id'] || @measure_def['id']
|
59
|
+
result = {:measure_id => @measure_id, :sub_id => @sub_id, :nqf_id => nqf_id, :population_ids => @measure_def["population_ids"],
|
39
60
|
:effective_date => @parameter_values['effective_date'],
|
40
61
|
:test_id => @parameter_values['test_id'], :filters => @parameter_values['filters']}
|
41
|
-
|
42
|
-
# need to time the old way agains the single query to verify that the single query is more performant
|
43
|
-
aggregate = {"population"=>0, "denominator"=>0, "numerator"=>0, "antinumerator"=>0, "exclusions"=>0}
|
44
|
-
%w(population denominator numerator antinumerator exclusions).each do |measure_group|
|
45
|
-
patient_cache.find(query.merge("value.#{measure_group}" => true)) do |cursor|
|
46
|
-
aggregate[measure_group] = cursor.count
|
47
|
-
end
|
48
|
-
end
|
49
|
-
aggregate["considered"] = patient_cache.find(query).count
|
50
|
-
aggregate["exclusions"] += patient_cache.find(base_query.merge({'value.manual_exclusion'=>true})).count
|
51
|
-
result.merge!(aggregate)
|
52
62
|
|
63
|
+
result.merge!(aggregate['result'].first)
|
64
|
+
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
|
53
66
|
result.merge!(execution_time: (Time.now.to_i - @parameter_values['start_time'].to_i)) if @parameter_values['start_time']
|
54
|
-
|
55
|
-
get_db
|
67
|
+
get_db()["query_cache"].insert(result)
|
68
|
+
get_db().command({:getLastError => 1}) # make sure last insert finished before we continue
|
56
69
|
result
|
57
70
|
end
|
58
71
|
|
@@ -60,13 +73,13 @@ module QME
|
|
60
73
|
# in the patient_cache collection. These documents will state the measure groups
|
61
74
|
# that the record belongs to, such as numerator, etc.
|
62
75
|
def map_records_into_measure_groups
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
76
|
+
measure = Builder.new(get_db(), @measure_def, @parameter_values)
|
77
|
+
get_db().command(:mapReduce => 'records',
|
78
|
+
:map => measure.map_function,
|
79
|
+
:reduce => "function(key, values){return values;}",
|
80
|
+
:out => {:reduce => 'patient_cache'},
|
81
|
+
:finalize => measure.finalize_function,
|
82
|
+
:query => {:test_id => @parameter_values['test_id']})
|
70
83
|
apply_manual_exclusions
|
71
84
|
end
|
72
85
|
|
@@ -74,13 +87,13 @@ module QME
|
|
74
87
|
# This will create a document in the patient_cache collection. This document
|
75
88
|
# will state the measure groups that the record belongs to, such as numerator, etc.
|
76
89
|
def map_record_into_measure_groups(patient_id)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
90
|
+
measure = Builder.new(get_db(), @measure_def, @parameter_values)
|
91
|
+
get_db().command(:mapReduce => 'records',
|
92
|
+
:map => measure.map_function,
|
93
|
+
:reduce => "function(key, values){return values;}",
|
94
|
+
:out => {:reduce => 'patient_cache'},
|
95
|
+
:finalize => measure.finalize_function,
|
96
|
+
:query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
|
84
97
|
apply_manual_exclusions
|
85
98
|
end
|
86
99
|
|
@@ -88,14 +101,14 @@ module QME
|
|
88
101
|
# This will *not* create a document in the patient_cache collection, instead the
|
89
102
|
# result is returned directly.
|
90
103
|
def get_patient_result(patient_id)
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
104
|
+
measure = Builder.new(get_db(), @measure_def, @parameter_values)
|
105
|
+
result = get_db().command(:mapReduce => 'records',
|
106
|
+
:map => measure.map_function,
|
107
|
+
:reduce => "function(key, values){return values;}",
|
108
|
+
:out => {:inline => true},
|
109
|
+
:raw => true,
|
110
|
+
:finalize => measure.finalize_function,
|
111
|
+
:query => {:medical_record_number => patient_id, :test_id => @parameter_values['test_id']})
|
99
112
|
raise result['err'] if result['ok']!=1
|
100
113
|
result['results'][0]['value']
|
101
114
|
end
|
@@ -104,12 +117,11 @@ module QME
|
|
104
117
|
# and sets a flag in each cached patient result for patients that have been excluded from the
|
105
118
|
# current measure
|
106
119
|
def apply_manual_exclusions
|
107
|
-
exclusions = get_db
|
120
|
+
exclusions = get_db()['manual_exclusions'].find({'measure_id'=>@measure_id, 'sub_id'=>@sub_id}).to_a.map do |exclusion|
|
108
121
|
exclusion['medical_record_id']
|
109
122
|
end
|
110
|
-
get_db
|
111
|
-
{'
|
112
|
-
{'$set'=>{'value.manual_exclusion'=>true}}, :multi=>true)
|
123
|
+
get_db()['patient_cache'].find({'value.measure_id'=>@measure_id, 'value.sub_id'=>@sub_id, 'value.medical_record_id'=>{'$in'=>exclusions} })
|
124
|
+
.update_all({'$set'=>{'value.manual_exclusion'=>true}})
|
113
125
|
end
|
114
126
|
|
115
127
|
def filter_parameters
|
@@ -117,7 +129,7 @@ module QME
|
|
117
129
|
conditions = []
|
118
130
|
if(filters = @parameter_values['filters'])
|
119
131
|
if (filters['providers'] && filters['providers'].size > 0)
|
120
|
-
providers = filters['providers'].map {|provider_id| BSON::ObjectId(provider_id) if (provider_id and provider_id != 'null') }
|
132
|
+
providers = filters['providers'].map {|provider_id| Moped::BSON::ObjectId(provider_id) if (provider_id and provider_id != 'null') }
|
121
133
|
# provider_performances have already been filtered by start and end date in map_reduce_builder as part of the finalize
|
122
134
|
conditions << {'value.provider_performances.provider_id' => {'$in' => providers}}
|
123
135
|
end
|
@@ -1,11 +1,8 @@
|
|
1
1
|
module QME
|
2
2
|
module MapReduce
|
3
|
-
# A
|
3
|
+
# A delayed_job that allows for measure calculation by a delayed_job worker. Can be created as follows:
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
7
|
-
# This will return a uuid which can be used to check in on the status of a job. More details on this can be found
|
8
|
-
# at the {Resque Stats project page}[https://github.com/quirkey/resque-status].
|
5
|
+
# Delayed::Job.enqueue QME::MapRedude::MeasureCalculationJob.new(:measure_id => '0221', :sub_id => 'a', :effective_date => 1291352400, :test_id => xyzzy)
|
9
6
|
#
|
10
7
|
# MeasureCalculationJob will check to see if a measure has been calculated before running the calculation. It does
|
11
8
|
# this by creating a QME::QualityReport and asking if it has been calculated. If so, it will complete the job without
|
@@ -13,36 +10,40 @@ module QME
|
|
13
10
|
#
|
14
11
|
# When a measure needs calculation, the job will create a QME::MapReduce::Executor and interact with it to calculate
|
15
12
|
# the report.
|
16
|
-
class MeasureCalculationJob
|
17
|
-
|
18
|
-
|
13
|
+
class MeasureCalculationJob
|
14
|
+
attr_accessor :test_id, :measure_id, :sub_id, :effective_date, :filters
|
15
|
+
|
16
|
+
def initialize(options)
|
17
|
+
@measure_id = options['measure_id']
|
18
|
+
@sub_id = options['sub_id']
|
19
|
+
@options = options
|
19
20
|
end
|
20
21
|
|
21
|
-
def
|
22
|
-
|
23
|
-
qr = QualityReport.new(options['measure_id'], options['sub_id'], 'effective_date' => options['effective_date'], 'test_id' => test_id, 'filters' => options['filters'])
|
22
|
+
def perform
|
23
|
+
qr = QualityReport.new(@measure_id, @sub_id, @options)
|
24
24
|
if qr.calculated?
|
25
|
-
completed("#{
|
25
|
+
completed("#{@measure_id}#{@sub_id} has already been calculated")
|
26
26
|
else
|
27
|
-
map = QME::MapReduce::Executor.new(
|
28
|
-
|
27
|
+
map = QME::MapReduce::Executor.new(@measure_id, @sub_id, @options.merge('start_time' => Time.now.to_i))
|
29
28
|
if !qr.patients_cached?
|
30
|
-
tick('Starting MapReduce')
|
29
|
+
tick('Starting MapReduce')
|
31
30
|
map.map_records_into_measure_groups
|
32
|
-
tick('MapReduce complete')
|
31
|
+
tick('MapReduce complete')
|
33
32
|
end
|
34
33
|
|
35
|
-
tick('Calculating group totals')
|
34
|
+
tick('Calculating group totals')
|
36
35
|
result = map.count_records_in_measure_groups
|
37
|
-
completed("#{
|
36
|
+
completed("#{@measure_id}#{@sub_id}: p#{result['population']}, d#{result['denominator']}, n#{result['numerator']}, excl#{result['exclusions']}, excep#{result['denexcep']}")
|
38
37
|
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def completed(message)
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
def tick(message)
|
39
45
|
|
40
46
|
end
|
41
|
-
|
42
|
-
# This can be uncommented and changed to put the jobs on a separate queue.
|
43
|
-
# def self.queue
|
44
|
-
# :statused
|
45
|
-
# end
|
46
47
|
end
|
47
48
|
end
|
48
49
|
end
|
data/lib/qme/quality_measure.rb
CHANGED
@@ -8,7 +8,7 @@ module QME
|
|
8
8
|
# @return [Hash] an hash of measure definitions
|
9
9
|
def self.all
|
10
10
|
result = {}
|
11
|
-
measures = get_db
|
11
|
+
measures = get_db()['measures']
|
12
12
|
measures.find().each do |measure|
|
13
13
|
id = measure['id']
|
14
14
|
sub_id = measure['sub_id']
|
@@ -19,7 +19,7 @@ module QME
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def self.get_measures(measure_ids)
|
22
|
-
get_db
|
22
|
+
get_db()['measures'].find('id' => {"$in" => measure_ids})
|
23
23
|
end
|
24
24
|
|
25
25
|
# Creates a new QualityMeasure
|
@@ -34,11 +34,11 @@ module QME
|
|
34
34
|
# Retrieve a measure definition from the database
|
35
35
|
# @return [Hash] a JSON hash of the encoded measure
|
36
36
|
def definition
|
37
|
-
measures = get_db
|
37
|
+
measures = get_db()['measures']
|
38
38
|
if @sub_id
|
39
|
-
measures.
|
39
|
+
measures.find({'id' => @measure_id, 'sub_id' => @sub_id}).first()
|
40
40
|
else
|
41
|
-
measures.
|
41
|
+
measures.find({'id' => @measure_id}).first()
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
data/lib/qme/quality_report.rb
CHANGED
@@ -10,25 +10,25 @@ module QME
|
|
10
10
|
# and query_cache collections
|
11
11
|
def self.destroy_all
|
12
12
|
determine_connection_information
|
13
|
-
get_db
|
14
|
-
get_db
|
13
|
+
get_db()["query_cache"].drop
|
14
|
+
get_db()["patient_cache"].drop
|
15
15
|
end
|
16
16
|
|
17
17
|
# Removes the cached results for the patient with the supplied id and
|
18
18
|
# recalculates as necessary
|
19
19
|
def self.update_patient_results(id)
|
20
|
-
determine_connection_information
|
20
|
+
determine_connection_information()
|
21
21
|
|
22
22
|
# TODO: need to wait for any outstanding calculations to complete and then prevent
|
23
23
|
# any new ones from starting until we are done.
|
24
24
|
|
25
25
|
# drop any cached measure result calculations for the modified patient
|
26
|
-
get_db
|
26
|
+
get_db()["patient_cache"].find('value.medical_record_id' => id).remove_all()
|
27
27
|
|
28
28
|
# get a list of cached measure results for a single patient
|
29
|
-
sample_patient = get_db
|
29
|
+
sample_patient = get_db()['patient_cache'].find().first()
|
30
30
|
if sample_patient
|
31
|
-
cached_results = get_db
|
31
|
+
cached_results = get_db()['patient_cache'].find({'value.patient_id' => sample_patient['value']['patient_id']})
|
32
32
|
|
33
33
|
# for each cached result (a combination of measure_id, sub_id, effective_date and test_id)
|
34
34
|
cached_results.each do |measure|
|
@@ -42,7 +42,7 @@ module QME
|
|
42
42
|
|
43
43
|
# remove the query totals so they will be recalculated using the new results for
|
44
44
|
# the modified patient
|
45
|
-
get_db
|
45
|
+
get_db()["query_cache"].drop()
|
46
46
|
end
|
47
47
|
|
48
48
|
# Creates a new QualityReport
|
@@ -74,29 +74,47 @@ module QME
|
|
74
74
|
# Kicks off a background job to calculate the measure
|
75
75
|
# @return a unique id for the measure calculation job
|
76
76
|
def calculate(asynchronous=true)
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
77
|
+
|
78
|
+
options = {'measure_id' => @measure_id, 'sub_id' => @sub_id}
|
79
|
+
|
80
|
+
options.merge! @parameter_values
|
81
|
+
options['filters'] = QME::QualityReport.normalize_filters(@parameter_values['filters'])
|
82
|
+
|
81
83
|
if (asynchronous)
|
82
|
-
MapReduce::MeasureCalculationJob.
|
84
|
+
job = Delayed::Job.enqueue(QME::MapReduce::MeasureCalculationJob.new(options))
|
85
|
+
job._id
|
83
86
|
else
|
84
|
-
MapReduce::MeasureCalculationJob.
|
87
|
+
mcj = QME::MapReduce::MeasureCalculationJob.new(options)
|
88
|
+
mcj.perform
|
85
89
|
end
|
86
90
|
end
|
87
91
|
|
88
92
|
# Returns the status of a measure calculation job
|
89
93
|
# @param job_id the id of the job to check on
|
90
|
-
# @return [
|
94
|
+
# @return [Symbol] Will return the status: :complete, :queued, :running, :failed
|
91
95
|
def status(job_id)
|
92
|
-
|
96
|
+
job = Delayed::Job.where(_id: job_id).first
|
97
|
+
if job.nil?
|
98
|
+
# If we can't find the job, we assume that it is complete
|
99
|
+
:complete
|
100
|
+
else
|
101
|
+
if job.locked_at.nil?
|
102
|
+
:queued
|
103
|
+
else
|
104
|
+
if job.failed?
|
105
|
+
:failed
|
106
|
+
else
|
107
|
+
:running
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
93
111
|
end
|
94
112
|
|
95
113
|
# Gets the result of running a quality measure
|
96
114
|
# @return [Hash] measure groups (like numerator) as keys, counts as values or nil if
|
97
115
|
# the measure has not yet been calculated
|
98
116
|
def result
|
99
|
-
cache = get_db
|
117
|
+
cache = get_db()["query_cache"]
|
100
118
|
query = {:measure_id => @measure_id, :sub_id => @sub_id,
|
101
119
|
:effective_date => @parameter_values['effective_date'],
|
102
120
|
:test_id => @parameter_values['test_id']}
|
@@ -106,7 +124,7 @@ module QME
|
|
106
124
|
query.merge!({filters: nil})
|
107
125
|
end
|
108
126
|
|
109
|
-
cache.
|
127
|
+
cache.find(query).first()
|
110
128
|
end
|
111
129
|
|
112
130
|
# make sure all filter id arrays are sorted
|
@@ -115,11 +133,11 @@ module QME
|
|
115
133
|
end
|
116
134
|
|
117
135
|
def patient_result
|
118
|
-
cache = get_db
|
136
|
+
cache = get_db()["patient_cache"]
|
119
137
|
query = {'value.measure_id' => @measure_id, 'value.sub_id' => @sub_id,
|
120
138
|
'value.effective_date' => @parameter_values['effective_date'],
|
121
139
|
'value.test_id' => @parameter_values['test_id']}
|
122
|
-
cache.
|
140
|
+
cache.find(query).first()
|
123
141
|
end
|
124
142
|
|
125
143
|
end
|
data/lib/qme/railtie.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'quality-measure-engine'
|
2
|
+
|
3
|
+
db_name = ENV['DB_NAME'] || 'test'
|
4
|
+
|
5
|
+
namespace :bundle do
|
6
|
+
desc 'Import a quality bundle into the database.'
|
7
|
+
task :import, :bundle_path, :delete_existing, :needs => :environment do |task, args|
|
8
|
+
raise "The path to the measures zip file must be specified" unless args.bundle_path
|
9
|
+
|
10
|
+
bundle = File.open(args.bundle_path)
|
11
|
+
importer = QME::Bundle::Importer.new(db_name)
|
12
|
+
importer.import(bundle, args.delete_existing)
|
13
|
+
end
|
14
|
+
end
|
data/lib/qme/version.rb
ADDED
@@ -1,32 +1,20 @@
|
|
1
1
|
require "bundler/setup"
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'moped'
|
4
|
+
require 'delayed_job_mongoid'
|
5
|
+
require 'zip/zip'
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
+
require "qme/version"
|
8
|
+
require 'qme/database_access'
|
9
|
+
require 'qme/quality_measure'
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
+
require 'qme/map/map_reduce_builder'
|
12
|
+
require 'qme/map/map_reduce_executor'
|
13
|
+
require 'qme/map/measure_calculation_job'
|
11
14
|
|
12
|
-
|
15
|
+
require 'qme/quality_report'
|
13
16
|
|
14
|
-
|
15
|
-
|
16
|
-
require_relative 'qme/randomizer/patient_randomization_job'
|
17
|
+
require 'qme/bundle/bundle'
|
18
|
+
require 'qme/bundle/importer'
|
17
19
|
|
18
|
-
require '
|
19
|
-
require 'health-data-standards'
|
20
|
-
|
21
|
-
require_relative 'qme/ext/record'
|
22
|
-
|
23
|
-
require_relative 'qme/importer/property_matcher'
|
24
|
-
require_relative 'qme/importer/generic_importer'
|
25
|
-
require_relative 'qme/importer/measure_properties_generator'
|
26
|
-
|
27
|
-
require 'json'
|
28
|
-
require 'mongo'
|
29
|
-
require 'nokogiri'
|
30
|
-
|
31
|
-
require_relative 'qme/measure/measure_loader'
|
32
|
-
require_relative 'qme/measure/database_loader'
|
20
|
+
require 'qme/railtie' if defined?(Rails)
|