quality-measure-engine 0.1.2 → 0.2.0

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.
Files changed (52) hide show
  1. data/Gemfile +9 -9
  2. data/README.md +39 -2
  3. data/Rakefile +25 -44
  4. data/js/map-reduce-utils.js +174 -0
  5. data/js/underscore-min.js +24 -0
  6. data/lib/qme/importer/code_system_helper.rb +26 -0
  7. data/lib/qme/importer/entry.rb +89 -0
  8. data/lib/qme/importer/generic_importer.rb +71 -0
  9. data/lib/qme/importer/hl7_helper.rb +27 -0
  10. data/lib/qme/importer/patient_importer.rb +150 -0
  11. data/lib/qme/importer/property_matcher.rb +103 -0
  12. data/lib/qme/importer/section_importer.rb +82 -0
  13. data/lib/qme/map/map_reduce_builder.rb +77 -147
  14. data/lib/qme/map/map_reduce_executor.rb +97 -13
  15. data/lib/qme/measure/database_loader.rb +90 -0
  16. data/lib/qme/measure/measure_loader.rb +141 -0
  17. data/lib/qme/mongo_helpers.rb +15 -0
  18. data/lib/qme/randomizer/patient_randomizer.rb +95 -0
  19. data/lib/qme_test.rb +13 -0
  20. data/lib/quality-measure-engine.rb +20 -4
  21. data/lib/tasks/measure.rake +76 -0
  22. data/lib/tasks/mongo.rake +74 -0
  23. data/lib/tasks/patient_random.rake +46 -0
  24. metadata +110 -156
  25. data/.gitignore +0 -6
  26. data/Gemfile.lock +0 -44
  27. data/fixtures/complex_measure.json +0 -36
  28. data/fixtures/result_example.json +0 -6
  29. data/lib/patches/v8.rb +0 -20
  30. data/lib/qme/query/json_document_builder.rb +0 -130
  31. data/lib/qme/query/json_query_executor.rb +0 -44
  32. data/measures/0032/0032_NQF_Cervical_Cancer_Screening.json +0 -171
  33. data/measures/0032/patients/denominator1.json +0 -10
  34. data/measures/0032/patients/denominator2.json +0 -10
  35. data/measures/0032/patients/numerator1.json +0 -11
  36. data/measures/0032/patients/population1.json +0 -9
  37. data/measures/0032/patients/population2.json +0 -11
  38. data/measures/0032/result/result.json +0 -6
  39. data/measures/0043/0043_NQF_PneumoniaVaccinationStatusForOlderAdults.json +0 -71
  40. data/measures/0043/patients/denominator.json +0 -11
  41. data/measures/0043/patients/numerator.json +0 -11
  42. data/measures/0043/patients/population.json +0 -10
  43. data/measures/0043/result/result.json +0 -6
  44. data/quality-measure-engine.gemspec +0 -97
  45. data/schema/result.json +0 -28
  46. data/schema/schema.json +0 -143
  47. data/spec/qme/map/map_reduce_builder_spec.rb +0 -64
  48. data/spec/qme/measures_spec.rb +0 -50
  49. data/spec/qme/query/json_document_builder_spec.rb +0 -56
  50. data/spec/schema_spec.rb +0 -21
  51. data/spec/spec_helper.rb +0 -7
  52. data/spec/validate_measures_spec.rb +0 -21
data/lib/qme_test.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'rspec/core/rake_task'
2
+ Dir[File.join(File.dirname(__FILE__),'tasks/*.rake')].sort.each do |ext|
3
+ load ext
4
+ end
5
+
6
+ RSpec::Core::RakeTask.new do |t|
7
+ t.rspec_opts = ["-c", "-f progress", "-r #{File.join(File.dirname(__FILE__),'../spec/spec_helper.rb')}"]
8
+ t.pattern = "#{File.join(File.dirname(__FILE__),'../spec/**/*measures_spec.rb')}"
9
+ end
10
+
11
+ RSpec::Core::RakeTask.new do |t|
12
+ t.rspec_opts = ["-c", "-f progress", "-r #{File.join(File.dirname(__FILE__),'../spec/spec_helper.rb')}"]
13
+ end
@@ -2,12 +2,28 @@ Bundler.require(:default)
2
2
 
3
3
  LIB = File.dirname(__FILE__)
4
4
 
5
- require LIB + '/patches/v8'
6
-
7
5
  require LIB + '/qme/map/map_reduce_builder'
8
6
  require LIB + '/qme/map/map_reduce_executor'
9
- require LIB + '/qme/query/json_document_builder'
10
- require LIB + '/qme/query/json_query_executor'
7
+
8
+ require LIB + '/qme/randomizer/patient_randomizer'
9
+
10
+ require 'singleton'
11
+
12
+ require LIB + '/qme/importer/entry'
13
+ require LIB + '/qme/importer/property_matcher'
14
+ require LIB + '/qme/importer/patient_importer'
15
+ require LIB + '/qme/importer/code_system_helper'
16
+ require LIB + '/qme/importer/hl7_helper'
17
+
18
+ require LIB + '/qme/importer/section_importer'
19
+ require LIB + '/qme/importer/generic_importer'
20
+
21
+ require LIB + '/qme/mongo_helpers'
11
22
 
12
23
  require 'json'
13
24
  require 'mongo'
25
+ require 'nokogiri'
26
+
27
+ require LIB + '/qme/measure/measure_loader'
28
+ require LIB + '/qme/measure/database_loader'
29
+
@@ -0,0 +1,76 @@
1
+ path = File.dirname(__FILE__)
2
+ path = path.index('lib') == 0 ? "./#{path}" : path
3
+ require 'json'
4
+ require 'zlib'
5
+ gem 'rubyzip'
6
+ require 'zip/zip'
7
+ require 'zip/zipfilesystem'
8
+
9
+
10
+ require File.join(path,'../quality-measure-engine')
11
+
12
+
13
+ measures_dir = ENV['MEASURE_DIR'] || 'measures'
14
+ puts "Loading measures from #{measures_dir}"
15
+
16
+ bundle_dir = ENV['BUNDLE_DIR'] || './'
17
+ namespace :measures do
18
+
19
+ desc 'Build all measures to tmp directory'
20
+ task :build do
21
+ dest_dir = File.join('.', 'tmp')
22
+ Dir.mkdir(dest_dir) if !Dir.exist?(dest_dir)
23
+ Dir.glob(File.join(measures_dir, '*')).each do |measure_dir|
24
+ measures = QME::Measure::Loader.load_measure(measure_dir)
25
+ measures.each do |measure|
26
+ id = measure['id']
27
+ sub_id = measure['sub_id']
28
+ json = JSON.pretty_generate(measure)
29
+ file_name = File.join(dest_dir, "#{id}#{sub_id}.json")
30
+ file = File.new(file_name, "w")
31
+ file.write(json)
32
+ file.close
33
+ end
34
+ end
35
+ end
36
+
37
+
38
+
39
+ desc "run the map_test tool"
40
+ task :map_tool do
41
+ require File.join(path,"../../map_test/map_test.rb")
42
+ end
43
+
44
+
45
+ desc "bundle measures into a compressed file for deployment"
46
+ task :bundle do
47
+
48
+ md = File.join(bundle_dir,measures_dir)
49
+ js = File.join(bundle_dir,'js')
50
+ bf = File.join(bundle_dir,'bundle.js')
51
+
52
+ tmp = './tmp'
53
+ bundle_tmp = File.join(tmp,'bundle')
54
+
55
+ md.sub!(%r[/$],'')
56
+ FileUtils.rm bundle_tmp, :force=>true
57
+ FileUtils.mkdir_p(bundle_tmp)
58
+ archive = File.join(tmp,'bundle.zip')
59
+ FileUtils.rm archive, :force=>true
60
+
61
+ Zip::ZipFile.open(archive, 'w') do |zipfile|
62
+ Dir["#{md}/**/**"].reject{|f|f==archive}.each do |file|
63
+ zipfile.add(file.sub(bundle_dir,''),file)
64
+ end
65
+
66
+ Dir["#{js}/**/**"].reject{|f|f==archive}.each do |file|
67
+ zipfile.add(file.sub(bundle_dir,''),file)
68
+ end
69
+
70
+ if File.exists?(bf)
71
+ zipfile.add(bf.sub(bundle_dir,''),bf)
72
+ end
73
+ end
74
+ end
75
+
76
+ end
@@ -0,0 +1,74 @@
1
+ path = File.dirname(__FILE__)
2
+ path = path.index('lib') == 0 ? "./#{path}" : path
3
+ require 'mongo'
4
+ require 'json'
5
+ require File.join(path,'../quality-measure-engine')
6
+
7
+ measures_dir = ENV['MEASURE_DIR'] || 'measures'
8
+ bundle_dir = ENV['BUNDLE_DIR'] || '.'
9
+ fixtures_dir = ENV['FIXTURE_DIR'] || File.join('fixtures', 'measures')
10
+ db_name = ENV['DB_NAME'] || 'test'
11
+ loader = QME::Database::Loader.new(db_name)
12
+
13
+ namespace :mongo do
14
+
15
+ desc 'Removed cached measure results'
16
+ task :drop_cache do
17
+ loader.drop_collection('query_cache')
18
+ end
19
+
20
+ desc 'Remove the patient records collection'
21
+ task :drop_records => :drop_cache do
22
+ loader.drop_collection('records')
23
+ end
24
+
25
+ desc 'Remove the measures and bundles collection'
26
+ task :drop_bundle => :drop_measures do
27
+ loader.drop_collection('bundles')
28
+ end
29
+
30
+ desc 'Remove the measures collection'
31
+ task :drop_measures => :drop_cache do
32
+ loader.drop_collection('measures')
33
+ end
34
+
35
+ desc 'Remove all measures and reload'
36
+ task :reload_measures => :drop_measures do
37
+ Dir.glob(File.join(measures_dir, '*')).each do |measure_dir|
38
+ loader.save_measure(measure_dir, 'measures')
39
+ end
40
+ end
41
+
42
+ desc 'Remove all patient records and reload'
43
+ task :reload_records => :drop_records do
44
+ load_files(loader, File.join(fixtures_dir,'*','patients','*.json'), 'records')
45
+ end
46
+
47
+ desc 'Remove all patient records and reload'
48
+ task :reload_bundle => [:drop_bundle] do
49
+ loader.save_bundle(bundle_dir,'bundles')
50
+ end
51
+
52
+ desc 'Clear database and road each measure and its sample patient files'
53
+ task :reload => [:reload_records, :reload_measures]
54
+
55
+ desc 'Seed the query cache by calculating the results for all measures'
56
+ task :seed_cache, [:year, :month, :day] do |t, args|
57
+ year = args.year.to_i>0 ? args.year.to_i : 2010
58
+ month = args.month.to_i>0 ? args.month.to_i : 9
59
+ day = args.day.to_i>0 ? args.day.to_i : 19
60
+ map = QME::MapReduce::Executor.new(loader.get_db)
61
+ map.all_measures.each_value do |measure_def|
62
+ result = map.measure_result(measure_def['id'], measure_def['sub_id'], :effective_date=>Time.gm(year, month, day).to_i)
63
+ puts "#{measure_def['id']}#{measure_def['sub_id']}: p#{result[:population]}, d#{result[:denominator]}, n#{result[:numerator]}, e#{result[:exclusions]}"
64
+ end
65
+ end
66
+
67
+ def load_files(loader, file_pattern, collection_name)
68
+ Dir.glob(file_pattern).each do |file|
69
+ json = JSON.parse(File.read(file))
70
+ loader.save(collection_name, json)
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,46 @@
1
+ path = File.dirname(__FILE__)
2
+ path = path.index('lib') == 0 ? "./#{path}" : path
3
+ require 'mongo'
4
+ require 'json'
5
+ require File.join(path,'../quality-measure-engine')
6
+
7
+ patient_template_dir = ENV['PATIENT_TEMPLATE_DIR'] || File.join('fixtures', 'patient_templates')
8
+ db_name = ENV['DB_NAME'] || 'test'
9
+ loader = QME::Database::Loader.new(db_name)
10
+
11
+ namespace :patient do
12
+
13
+ desc 'Generate n (default 10) random patient records and save them in the database'
14
+ task :random, [:n] => ['mongo:drop_records', 'mongo:reload_measures'] do |t, args|
15
+ n = args.n.to_i>0 ? args.n.to_i : 1
16
+
17
+ templates = []
18
+ Dir.glob(File.join(patient_template_dir, '*.json.erb')).each do |file|
19
+ templates << File.read(file)
20
+ end
21
+
22
+ if templates.length<1
23
+ puts "No patient templates in #{patient_template_dir}"
24
+ return
25
+ end
26
+
27
+ map = QME::MapReduce::Executor.new(loader.get_db)
28
+ processed_measures = {}
29
+ map.all_measures.each_value do |measure_def|
30
+ measure_id = measure_def['id']
31
+ if !processed_measures[measure_id]
32
+ QME::Importer::PatientImporter.instance.add_measure(measure_id, QME::Importer::GenericImporter.new(measure_def))
33
+ processed_measures[measure_id]=true
34
+ end
35
+ end
36
+
37
+ n.times do
38
+ template = templates[rand(templates.length)]
39
+ generator = QME::Randomizer::Patient.new(template)
40
+ json = JSON.parse(generator.get())
41
+ patient_record = QME::Importer::PatientImporter.instance.parse_hash(json)
42
+ loader.save('records', patient_record)
43
+ end
44
+ end
45
+
46
+ end
metadata CHANGED
@@ -1,192 +1,146 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quality-measure-engine
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 1
8
- - 2
9
- version: 0.1.2
4
+ prerelease:
5
+ version: 0.2.0
10
6
  platform: ruby
11
7
  authors:
12
- - Marc Hadley
13
- - Andy Gregorowicz
8
+ - Marc Hadley
9
+ - Andy Gregorowicz
10
+ - Rob Dingwell
14
11
  autorequire:
15
12
  bindir: bin
16
13
  cert_chain: []
17
14
 
18
- date: 2010-11-01 00:00:00 -04:00
15
+ date: 2011-02-23 00:00:00 -05:00
19
16
  default_executable:
20
17
  dependencies:
21
- - !ruby/object:Gem::Dependency
22
- name: mongo
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- segments:
30
- - 1
31
- - 1
32
- version: "1.1"
33
- type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: therubyracer
37
- prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
39
- none: false
40
- requirements:
41
- - - ~>
42
- - !ruby/object:Gem::Version
43
- segments:
44
- - 0
45
- - 7
46
- - 5
47
- version: 0.7.5
48
- type: :runtime
49
- version_requirements: *id002
50
- - !ruby/object:Gem::Dependency
51
- name: jsonschema
52
- prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
54
- none: false
55
- requirements:
56
- - - ~>
57
- - !ruby/object:Gem::Version
58
- segments:
59
- - 2
60
- - 0
61
- - 0
62
- version: 2.0.0
63
- type: :development
64
- version_requirements: *id003
65
- - !ruby/object:Gem::Dependency
66
- name: rspec
67
- prerelease: false
68
- requirement: &id004 !ruby/object:Gem::Requirement
69
- none: false
70
- requirements:
71
- - - ~>
72
- - !ruby/object:Gem::Version
73
- segments:
74
- - 2
75
- - 0
76
- - 0
77
- version: 2.0.0
78
- type: :development
79
- version_requirements: *id004
80
- - !ruby/object:Gem::Dependency
81
- name: awesome_print
82
- prerelease: false
83
- requirement: &id005 !ruby/object:Gem::Requirement
84
- none: false
85
- requirements:
86
- - - ~>
87
- - !ruby/object:Gem::Version
88
- segments:
89
- - 0
90
- - 2
91
- - 1
92
- version: 0.2.1
93
- type: :development
94
- version_requirements: *id005
95
- - !ruby/object:Gem::Dependency
96
- name: jeweler
97
- prerelease: false
98
- requirement: &id006 !ruby/object:Gem::Requirement
99
- none: false
100
- requirements:
101
- - - ~>
102
- - !ruby/object:Gem::Version
103
- segments:
104
- - 1
105
- - 4
106
- - 0
107
- version: 1.4.0
108
- type: :development
109
- version_requirements: *id006
18
+ - !ruby/object:Gem::Dependency
19
+ name: mongo
20
+ prerelease: false
21
+ requirement: &id001 !ruby/object:Gem::Requirement
22
+ none: false
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: "1.2"
27
+ type: :runtime
28
+ version_requirements: *id001
29
+ - !ruby/object:Gem::Dependency
30
+ name: rubyzip
31
+ prerelease: false
32
+ requirement: &id002 !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 0.9.4
38
+ type: :runtime
39
+ version_requirements: *id002
40
+ - !ruby/object:Gem::Dependency
41
+ name: nokogiri
42
+ prerelease: false
43
+ requirement: &id003 !ruby/object:Gem::Requirement
44
+ none: false
45
+ requirements:
46
+ - - ~>
47
+ - !ruby/object:Gem::Version
48
+ version: 1.4.4
49
+ type: :runtime
50
+ version_requirements: *id003
51
+ - !ruby/object:Gem::Dependency
52
+ name: jsonschema
53
+ prerelease: false
54
+ requirement: &id004 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ~>
58
+ - !ruby/object:Gem::Version
59
+ version: 2.0.0
60
+ type: :development
61
+ version_requirements: *id004
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ prerelease: false
65
+ requirement: &id005 !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ version: 2.5.0
71
+ type: :development
72
+ version_requirements: *id005
73
+ - !ruby/object:Gem::Dependency
74
+ name: awesome_print
75
+ prerelease: false
76
+ requirement: &id006 !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ~>
80
+ - !ruby/object:Gem::Version
81
+ version: 0.2.1
82
+ type: :development
83
+ version_requirements: *id006
110
84
  description: A library for extracting quality measure information from HITSP C32's and ASTM CCR's
111
85
  email: talk@projectpophealth.org
112
86
  executables: []
113
87
 
114
88
  extensions: []
115
89
 
116
- extra_rdoc_files:
117
- - README.md
90
+ extra_rdoc_files: []
91
+
118
92
  files:
119
- - .gitignore
120
- - Gemfile
121
- - Gemfile.lock
122
- - README.md
123
- - Rakefile
124
- - VERSION
125
- - fixtures/complex_measure.json
126
- - fixtures/result_example.json
127
- - lib/patches/v8.rb
128
- - lib/qme/map/map_reduce_builder.rb
129
- - lib/qme/map/map_reduce_executor.rb
130
- - lib/qme/query/json_document_builder.rb
131
- - lib/qme/query/json_query_executor.rb
132
- - lib/quality-measure-engine.rb
133
- - measures/0032/0032_NQF_Cervical_Cancer_Screening.json
134
- - measures/0032/patients/denominator1.json
135
- - measures/0032/patients/denominator2.json
136
- - measures/0032/patients/numerator1.json
137
- - measures/0032/patients/population1.json
138
- - measures/0032/patients/population2.json
139
- - measures/0032/result/result.json
140
- - measures/0043/0043_NQF_PneumoniaVaccinationStatusForOlderAdults.json
141
- - measures/0043/patients/denominator.json
142
- - measures/0043/patients/numerator.json
143
- - measures/0043/patients/population.json
144
- - measures/0043/result/result.json
145
- - quality-measure-engine.gemspec
146
- - schema/result.json
147
- - schema/schema.json
148
- - spec/qme/map/map_reduce_builder_spec.rb
149
- - spec/qme/measures_spec.rb
150
- - spec/qme/query/json_document_builder_spec.rb
151
- - spec/schema_spec.rb
152
- - spec/spec_helper.rb
153
- - spec/validate_measures_spec.rb
93
+ - lib/qme_test.rb
94
+ - lib/quality-measure-engine.rb
95
+ - lib/qme/mongo_helpers.rb
96
+ - lib/qme/importer/code_system_helper.rb
97
+ - lib/qme/importer/entry.rb
98
+ - lib/qme/importer/generic_importer.rb
99
+ - lib/qme/importer/hl7_helper.rb
100
+ - lib/qme/importer/patient_importer.rb
101
+ - lib/qme/importer/property_matcher.rb
102
+ - lib/qme/importer/section_importer.rb
103
+ - lib/qme/map/map_reduce_builder.rb
104
+ - lib/qme/map/map_reduce_executor.rb
105
+ - lib/qme/measure/database_loader.rb
106
+ - lib/qme/measure/measure_loader.rb
107
+ - lib/qme/randomizer/patient_randomizer.rb
108
+ - lib/tasks/measure.rake
109
+ - lib/tasks/mongo.rake
110
+ - lib/tasks/patient_random.rake
111
+ - js/map-reduce-utils.js
112
+ - js/underscore-min.js
113
+ - Gemfile
114
+ - README.md
115
+ - Rakefile
116
+ - VERSION
154
117
  has_rdoc: true
155
118
  homepage: http://github.com/pophealth/quality-measure-engine
156
119
  licenses: []
157
120
 
158
121
  post_install_message:
159
- rdoc_options:
160
- - --charset=UTF-8
122
+ rdoc_options: []
123
+
161
124
  require_paths:
162
- - lib
125
+ - lib
163
126
  required_ruby_version: !ruby/object:Gem::Requirement
164
127
  none: false
165
128
  requirements:
166
- - - ">="
167
- - !ruby/object:Gem::Version
168
- segments:
169
- - 0
170
- version: "0"
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: "0"
171
132
  required_rubygems_version: !ruby/object:Gem::Requirement
172
133
  none: false
173
134
  requirements:
174
- - - ">="
175
- - !ruby/object:Gem::Version
176
- segments:
177
- - 0
178
- version: "0"
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: "0"
179
138
  requirements: []
180
139
 
181
140
  rubyforge_project:
182
- rubygems_version: 1.3.7
141
+ rubygems_version: 1.5.0
183
142
  signing_key:
184
143
  specification_version: 3
185
144
  summary: A library for extracting quality measure information from HITSP C32's and ASTM CCR's
186
- test_files:
187
- - spec/qme/map/map_reduce_builder_spec.rb
188
- - spec/qme/measures_spec.rb
189
- - spec/qme/query/json_document_builder_spec.rb
190
- - spec/schema_spec.rb
191
- - spec/spec_helper.rb
192
- - spec/validate_measures_spec.rb
145
+ test_files: []
146
+