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.
Files changed (66) hide show
  1. data/.gitignore +12 -0
  2. data/.travis.yml +16 -0
  3. data/Gemfile +5 -21
  4. data/Gemfile.lock +126 -0
  5. data/LICENSE.txt +13 -0
  6. data/README.md +23 -44
  7. data/Rakefile +6 -29
  8. data/lib/qme/bundle/bundle.rb +34 -0
  9. data/lib/qme/bundle/importer.rb +69 -0
  10. data/lib/qme/database_access.rb +7 -11
  11. data/lib/qme/map/map_reduce_builder.rb +4 -1
  12. data/lib/qme/map/map_reduce_executor.rb +55 -43
  13. data/lib/qme/map/measure_calculation_job.rb +24 -23
  14. data/lib/qme/quality_measure.rb +5 -5
  15. data/lib/qme/quality_report.rb +37 -19
  16. data/lib/qme/railtie.rb +7 -0
  17. data/lib/qme/tasks/bundle.rake +14 -0
  18. data/lib/qme/version.rb +3 -0
  19. data/lib/quality-measure-engine.rb +13 -25
  20. data/quality-measure-engine.gemspec +28 -0
  21. data/test/fixtures/bundles/just_measure_0002.zip +0 -0
  22. data/test/fixtures/delayed_backend_mongoid_jobs/queued_job.json +9 -0
  23. data/test/fixtures/measures/measure_metadata.json +52 -0
  24. data/test/fixtures/records/barry_berry.json +471 -0
  25. data/test/fixtures/records/billy_jones_ipp.json +78 -0
  26. data/test/fixtures/records/jane_jones_numerator.json +120 -0
  27. data/test/fixtures/records/jill_jones_denominator.json +78 -0
  28. data/test/simplecov_setup.rb +18 -0
  29. data/test/test_helper.rb +26 -0
  30. data/test/unit/qme/map/map_reduce_builder_test.rb +38 -0
  31. data/test/unit/qme/map/map_reduce_executor_test.rb +56 -0
  32. data/test/unit/qme/map/measure_calculation_job_test.rb +22 -0
  33. data/test/unit/qme/quality_measure_test.rb +14 -0
  34. data/{spec/qme/quality_report_spec.rb → test/unit/qme/quality_report_test.rb} +32 -20
  35. metadata +91 -115
  36. data/VERSION +0 -1
  37. data/js/map_reduce_utils.js +0 -173
  38. data/js/underscore_min.js +0 -25
  39. data/lib/qme/ext/record.rb +0 -43
  40. data/lib/qme/importer/entry.rb +0 -126
  41. data/lib/qme/importer/generic_importer.rb +0 -117
  42. data/lib/qme/importer/measure_properties_generator.rb +0 -39
  43. data/lib/qme/importer/property_matcher.rb +0 -110
  44. data/lib/qme/measure/database_loader.rb +0 -83
  45. data/lib/qme/measure/measure_loader.rb +0 -174
  46. data/lib/qme/measure/properties_builder.rb +0 -184
  47. data/lib/qme/measure/properties_converter.rb +0 -27
  48. data/lib/qme/randomizer/patient_randomization_job.rb +0 -47
  49. data/lib/qme/randomizer/patient_randomizer.rb +0 -250
  50. data/lib/qme/randomizer/random_patient_creator.rb +0 -47
  51. data/lib/qme_test.rb +0 -13
  52. data/lib/tasks/fixtures.rake +0 -91
  53. data/lib/tasks/measure.rake +0 -110
  54. data/lib/tasks/mongo.rake +0 -68
  55. data/lib/tasks/patient_random.rake +0 -45
  56. data/spec/qme/bundle_spec.rb +0 -37
  57. data/spec/qme/importer/generic_importer_spec.rb +0 -73
  58. data/spec/qme/importer/measure_properties_generator_spec.rb +0 -15
  59. data/spec/qme/importer/property_matcher_spec.rb +0 -174
  60. data/spec/qme/map/map_reduce_builder_spec.rb +0 -38
  61. data/spec/qme/map/measures_spec.rb +0 -38
  62. data/spec/qme/map/patient_mapper_spec.rb +0 -11
  63. data/spec/qme/measure_loader_spec.rb +0 -12
  64. data/spec/qme/properties_builder_spec.rb +0 -61
  65. data/spec/spec_helper.rb +0 -120
  66. data/spec/validate_measures_spec.rb +0 -21
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ class QualityMeasureTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ importer = QME::Bundle::Importer.new
6
+ importer.import(File.new('test/fixtures/bundles/just_measure_0002.zip'), true)
7
+ end
8
+
9
+ def test_getting_all_measures
10
+ all_measures = QME::QualityMeasure.all
11
+ assert_equal 1, all_measures.size
12
+ assert all_measures["2E679CD2-3FEC-4A75-A75A-61403E5EFEE8.json"]
13
+ end
14
+ end
@@ -1,9 +1,12 @@
1
- describe QME::QualityReport do
2
- before do
3
- loader = QME::Database::Loader.new
4
- loader.drop_collection('query_cache')
5
- loader.drop_collection('patient_cache')
6
- loader.get_db['query_cache'].save(
1
+ require 'test_helper'
2
+
3
+ class QualityReportTest < MiniTest::Unit::TestCase
4
+ include QME::DatabaseAccess
5
+
6
+ def setup
7
+ get_db()['query_cache'].drop()
8
+ get_db()['patient_cache'].drop()
9
+ get_db()['query_cache'].insert(
7
10
  "measure_id" => "test2",
8
11
  "sub_id" => "b",
9
12
  "initialPopulation" => 4,
@@ -12,7 +15,7 @@ describe QME::QualityReport do
12
15
  "exclusions" => 1,
13
16
  "effective_date" => Time.gm(2010, 9, 19).to_i
14
17
  )
15
- loader.get_db['patient_cache'].save(
18
+ get_db()['patient_cache'].insert(
16
19
  "value" => {
17
20
  "population" => false,
18
21
  "denominator" => false,
@@ -40,35 +43,44 @@ describe QME::QualityReport do
40
43
  }
41
44
  )
42
45
  end
43
-
44
- it "should be able to determine if it has been calculated" do
46
+
47
+ def test_calculated
45
48
  qr = QME::QualityReport.new('test2', 'b', "effective_date" => Time.gm(2010, 9, 19).to_i)
46
- qr.calculated?.should be_true
49
+ assert qr.calculated?
47
50
 
48
51
  qr = QME::QualityReport.new('test2', 'b', "effective_date" => Time.gm(2010, 9, 20).to_i)
49
- qr.calculated?.should be_false
52
+ assert !qr.calculated?
50
53
  end
51
54
 
52
- it "should return the result of a calculated quality measure" do
55
+ def test_result
53
56
  qr = QME::QualityReport.new('test2', 'b', "effective_date" => Time.gm(2010, 9, 19).to_i)
54
57
  result = qr.result
55
58
 
56
- result['numerator'].should == 1
59
+ assert_equal 1, result['numerator']
57
60
  end
58
61
 
59
- it "should be able to clear all of the quality reports" do
62
+ def test_destroy_all
60
63
  QME::QualityReport.destroy_all
61
64
 
62
65
  qr = QME::QualityReport.new('test2', 'b', "effective_date" => Time.gm(2010, 9, 19).to_i)
63
- qr.calculated?.should be_false
66
+ assert !qr.calculated?
64
67
  end
65
68
 
66
- it "should be remove results for updated patients" do
69
+ def test_update_patient_results
67
70
  qr = QME::QualityReport.new('test2', 'b', "effective_date" => Time.gm(2010, 9, 19).to_i)
68
- qr.calculated?.should be_true
69
- qr.patients_cached?.should be_true
71
+ assert qr.calculated?
72
+ assert qr.patients_cached?
70
73
  QME::QualityReport.update_patient_results("0616911582")
71
- qr.calculated?.should be_false
72
- qr.patients_cached?.should be_false
74
+ assert !qr.calculated?
75
+ assert !qr.patients_cached?
76
+ end
77
+
78
+ def test_status
79
+ qr = QME::QualityReport.new('test2', 'b', "effective_date" => Time.gm(2010, 9, 19).to_i)
80
+ status = qr.status('not really a job id')
81
+ assert_equal :complete, status
82
+ status = qr.status("508aeff07042f9f88900000d")
83
+ assert_equal :queued, status
73
84
  end
85
+
74
86
  end
metadata CHANGED
@@ -1,211 +1,173 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quality-measure-engine
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.5
4
+ version: 2.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Marc Hadley
9
9
  - Andy Gregorowicz
10
10
  - Rob Dingwell
11
+ - Adam Goldstein
11
12
  autorequire:
12
13
  bindir: bin
13
14
  cert_chain: []
14
- date: 2012-07-03 00:00:00.000000000Z
15
+ date: 2012-10-31 00:00:00.000000000 Z
15
16
  dependencies:
16
17
  - !ruby/object:Gem::Dependency
17
- name: mongo
18
- requirement: &2153471000 !ruby/object:Gem::Requirement
18
+ name: moped
19
+ requirement: !ruby/object:Gem::Requirement
19
20
  none: false
20
21
  requirements:
21
22
  - - ~>
22
23
  - !ruby/object:Gem::Version
23
- version: '1.3'
24
+ version: 1.2.7
24
25
  type: :runtime
25
26
  prerelease: false
26
- version_requirements: *2153471000
27
- - !ruby/object:Gem::Dependency
28
- name: rubyzip
29
- requirement: &2153470520 !ruby/object:Gem::Requirement
27
+ version_requirements: !ruby/object:Gem::Requirement
30
28
  none: false
31
29
  requirements:
32
30
  - - ~>
33
31
  - !ruby/object:Gem::Version
34
- version: 0.9.4
35
- type: :runtime
36
- prerelease: false
37
- version_requirements: *2153470520
32
+ version: 1.2.7
38
33
  - !ruby/object:Gem::Dependency
39
- name: nokogiri
40
- requirement: &2153469980 !ruby/object:Gem::Requirement
34
+ name: mongoid
35
+ requirement: !ruby/object:Gem::Requirement
41
36
  none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ~>
44
39
  - !ruby/object:Gem::Version
45
- version: 1.4.4
40
+ version: 3.0.9
46
41
  type: :runtime
47
42
  prerelease: false
48
- version_requirements: *2153469980
49
- - !ruby/object:Gem::Dependency
50
- name: resque
51
- requirement: &2153469500 !ruby/object:Gem::Requirement
43
+ version_requirements: !ruby/object:Gem::Requirement
52
44
  none: false
53
45
  requirements:
54
46
  - - ~>
55
47
  - !ruby/object:Gem::Version
56
- version: 1.15.0
57
- type: :runtime
58
- prerelease: false
59
- version_requirements: *2153469500
48
+ version: 3.0.9
60
49
  - !ruby/object:Gem::Dependency
61
- name: redis
62
- requirement: &2153468840 !ruby/object:Gem::Requirement
50
+ name: rubyzip
51
+ requirement: !ruby/object:Gem::Requirement
63
52
  none: false
64
53
  requirements:
65
54
  - - ~>
66
55
  - !ruby/object:Gem::Version
67
- version: 2.2.2
56
+ version: 0.9.9
68
57
  type: :runtime
69
58
  prerelease: false
70
- version_requirements: *2153468840
59
+ version_requirements: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ~>
63
+ - !ruby/object:Gem::Version
64
+ version: 0.9.9
71
65
  - !ruby/object:Gem::Dependency
72
- name: resque-status
73
- requirement: &2153463060 !ruby/object:Gem::Requirement
66
+ name: delayed_job_mongoid
67
+ requirement: !ruby/object:Gem::Requirement
74
68
  none: false
75
69
  requirements:
76
70
  - - ~>
77
71
  - !ruby/object:Gem::Version
78
- version: 0.2.3
72
+ version: 2.0.0
79
73
  type: :runtime
80
74
  prerelease: false
81
- version_requirements: *2153463060
82
- - !ruby/object:Gem::Dependency
83
- name: jsonschema
84
- requirement: &2153461740 !ruby/object:Gem::Requirement
75
+ version_requirements: !ruby/object:Gem::Requirement
85
76
  none: false
86
77
  requirements:
87
78
  - - ~>
88
79
  - !ruby/object:Gem::Version
89
80
  version: 2.0.0
90
- type: :development
91
- prerelease: false
92
- version_requirements: *2153461740
93
81
  - !ruby/object:Gem::Dependency
94
- name: rspec
95
- requirement: &2153460480 !ruby/object:Gem::Requirement
82
+ name: minitest
83
+ requirement: !ruby/object:Gem::Requirement
96
84
  none: false
97
85
  requirements:
98
86
  - - ~>
99
87
  - !ruby/object:Gem::Version
100
- version: 2.5.0
88
+ version: 4.1.0
101
89
  type: :development
102
90
  prerelease: false
103
- version_requirements: *2153460480
104
- - !ruby/object:Gem::Dependency
105
- name: awesome_print
106
- requirement: &2153459880 !ruby/object:Gem::Requirement
91
+ version_requirements: !ruby/object:Gem::Requirement
107
92
  none: false
108
93
  requirements:
109
94
  - - ~>
110
95
  - !ruby/object:Gem::Version
111
- version: '0.3'
112
- type: :development
113
- prerelease: false
114
- version_requirements: *2153459880
96
+ version: 4.1.0
115
97
  - !ruby/object:Gem::Dependency
116
- name: roo
117
- requirement: &2153458460 !ruby/object:Gem::Requirement
98
+ name: simplecov
99
+ requirement: !ruby/object:Gem::Requirement
118
100
  none: false
119
101
  requirements:
120
102
  - - ~>
121
103
  - !ruby/object:Gem::Version
122
- version: 1.9.3
104
+ version: 0.7.1
123
105
  type: :development
124
106
  prerelease: false
125
- version_requirements: *2153458460
126
- - !ruby/object:Gem::Dependency
127
- name: builder
128
- requirement: &2153456780 !ruby/object:Gem::Requirement
107
+ version_requirements: !ruby/object:Gem::Requirement
129
108
  none: false
130
109
  requirements:
131
110
  - - ~>
132
111
  - !ruby/object:Gem::Version
133
- version: 3.0.0
134
- type: :development
135
- prerelease: false
136
- version_requirements: *2153456780
112
+ version: 0.7.1
137
113
  - !ruby/object:Gem::Dependency
138
- name: spreadsheet
139
- requirement: &2153455880 !ruby/object:Gem::Requirement
114
+ name: rails
115
+ requirement: !ruby/object:Gem::Requirement
140
116
  none: false
141
117
  requirements:
142
118
  - - ~>
143
119
  - !ruby/object:Gem::Version
144
- version: 0.6.5.2
120
+ version: 3.2.8
145
121
  type: :development
146
122
  prerelease: false
147
- version_requirements: *2153455880
148
- - !ruby/object:Gem::Dependency
149
- name: google-spreadsheet-ruby
150
- requirement: &2153410360 !ruby/object:Gem::Requirement
123
+ version_requirements: !ruby/object:Gem::Requirement
151
124
  none: false
152
125
  requirements:
153
126
  - - ~>
154
127
  - !ruby/object:Gem::Version
155
- version: 0.1.2
156
- type: :development
157
- prerelease: false
158
- version_requirements: *2153410360
159
- description: A library for extracting quality measure information from HITSP C32's
160
- and ASTM CCR's
161
- email: talk@projectpophealth.org
128
+ version: 3.2.8
129
+ description: A library for running clinical quality measures
130
+ email:
131
+ - talk@projectpophealth.org
162
132
  executables: []
163
133
  extensions: []
164
134
  extra_rdoc_files: []
165
135
  files:
136
+ - .gitignore
137
+ - .travis.yml
138
+ - Gemfile
139
+ - Gemfile.lock
140
+ - LICENSE.txt
141
+ - README.md
142
+ - Rakefile
143
+ - lib/qme/bundle/bundle.rb
144
+ - lib/qme/bundle/importer.rb
166
145
  - lib/qme/database_access.rb
167
- - lib/qme/ext/record.rb
168
- - lib/qme/importer/entry.rb
169
- - lib/qme/importer/generic_importer.rb
170
- - lib/qme/importer/measure_properties_generator.rb
171
- - lib/qme/importer/property_matcher.rb
172
146
  - lib/qme/map/map_reduce_builder.rb
173
147
  - lib/qme/map/map_reduce_executor.rb
174
148
  - lib/qme/map/measure_calculation_job.rb
175
- - lib/qme/measure/database_loader.rb
176
- - lib/qme/measure/measure_loader.rb
177
- - lib/qme/measure/properties_builder.rb
178
- - lib/qme/measure/properties_converter.rb
179
149
  - lib/qme/quality_measure.rb
180
150
  - lib/qme/quality_report.rb
181
- - lib/qme/randomizer/patient_randomization_job.rb
182
- - lib/qme/randomizer/patient_randomizer.rb
183
- - lib/qme/randomizer/random_patient_creator.rb
184
- - lib/qme_test.rb
151
+ - lib/qme/railtie.rb
152
+ - lib/qme/tasks/bundle.rake
153
+ - lib/qme/version.rb
185
154
  - lib/quality-measure-engine.rb
186
- - lib/tasks/fixtures.rake
187
- - lib/tasks/measure.rake
188
- - lib/tasks/mongo.rake
189
- - lib/tasks/patient_random.rake
190
- - js/map_reduce_utils.js
191
- - js/underscore_min.js
192
- - spec/qme/bundle_spec.rb
193
- - spec/qme/importer/generic_importer_spec.rb
194
- - spec/qme/importer/measure_properties_generator_spec.rb
195
- - spec/qme/importer/property_matcher_spec.rb
196
- - spec/qme/map/map_reduce_builder_spec.rb
197
- - spec/qme/map/measures_spec.rb
198
- - spec/qme/map/patient_mapper_spec.rb
199
- - spec/qme/measure_loader_spec.rb
200
- - spec/qme/properties_builder_spec.rb
201
- - spec/qme/quality_report_spec.rb
202
- - spec/spec_helper.rb
203
- - spec/validate_measures_spec.rb
204
- - Gemfile
205
- - README.md
206
- - Rakefile
207
- - VERSION
208
- homepage: http://github.com/pophealth/quality-measure-engine
155
+ - quality-measure-engine.gemspec
156
+ - test/fixtures/bundles/just_measure_0002.zip
157
+ - test/fixtures/delayed_backend_mongoid_jobs/queued_job.json
158
+ - test/fixtures/measures/measure_metadata.json
159
+ - test/fixtures/records/barry_berry.json
160
+ - test/fixtures/records/billy_jones_ipp.json
161
+ - test/fixtures/records/jane_jones_numerator.json
162
+ - test/fixtures/records/jill_jones_denominator.json
163
+ - test/simplecov_setup.rb
164
+ - test/test_helper.rb
165
+ - test/unit/qme/map/map_reduce_builder_test.rb
166
+ - test/unit/qme/map/map_reduce_executor_test.rb
167
+ - test/unit/qme/map/measure_calculation_job_test.rb
168
+ - test/unit/qme/quality_measure_test.rb
169
+ - test/unit/qme/quality_report_test.rb
170
+ homepage: http://www.projectpophealth.org
209
171
  licenses: []
210
172
  post_install_message:
211
173
  rdoc_options: []
@@ -225,10 +187,24 @@ required_rubygems_version: !ruby/object:Gem::Requirement
225
187
  version: '0'
226
188
  requirements: []
227
189
  rubyforge_project:
228
- rubygems_version: 1.8.10
190
+ rubygems_version: 1.8.24
229
191
  signing_key:
230
192
  specification_version: 3
231
- summary: A library for extracting quality measure information from HITSP C32's and
232
- ASTM CCR's
233
- test_files: []
193
+ summary: This library can run JavaScript based clinical quality measures on a repository
194
+ of patients stored in MongoDB
195
+ test_files:
196
+ - test/fixtures/bundles/just_measure_0002.zip
197
+ - test/fixtures/delayed_backend_mongoid_jobs/queued_job.json
198
+ - test/fixtures/measures/measure_metadata.json
199
+ - test/fixtures/records/barry_berry.json
200
+ - test/fixtures/records/billy_jones_ipp.json
201
+ - test/fixtures/records/jane_jones_numerator.json
202
+ - test/fixtures/records/jill_jones_denominator.json
203
+ - test/simplecov_setup.rb
204
+ - test/test_helper.rb
205
+ - test/unit/qme/map/map_reduce_builder_test.rb
206
+ - test/unit/qme/map/map_reduce_executor_test.rb
207
+ - test/unit/qme/map/measure_calculation_job_test.rb
208
+ - test/unit/qme/quality_measure_test.rb
209
+ - test/unit/qme/quality_report_test.rb
234
210
  has_rdoc:
data/VERSION DELETED
@@ -1 +0,0 @@
1
- 1.1.0
@@ -1,173 +0,0 @@
1
- function() {
2
- // Adds common utility functions to the root JS object. These are then
3
- // available for use by the map-reduce functions for each measure.
4
- // lib/qme/mongo_helpers.rb executes this function on a database
5
- // connection.
6
-
7
- var root = this;
8
-
9
- // Takes an arbitrary number of arrays and single values and returns a flattened
10
- // array of all of the elements with any null values removed. For efficiency, if
11
- // called with just a single array then it simply returns that array
12
- root.normalize = function() {
13
- if (arguments.length==1 && _.isArray(arguments[0]))
14
- return arguments[0];
15
- return _.compact(_.flatten(arguments));
16
- }
17
-
18
- // returns the number of values which fall between the supplied limits
19
- // value may be a number or an array of numbers
20
- root.inRange = function(value, min, max) {
21
- value = normalize(value);
22
- var count = 0;
23
- for (i=0;i<value.length;i++) {
24
- if ((value[i]>=min) && (value[i]<=max))
25
- count++;
26
- }
27
- return count;
28
- };
29
-
30
- // returns the largest member of value that is within the supplied range
31
- root.maxInRange = function(value, min, max) {
32
- value = normalize(value);
33
- var allInRange = _.select(value, function(v) {return v>=min && v<=max;});
34
- return _.max(allInRange);
35
- }
36
-
37
- // returns the number of values which are less than the supplied limit
38
- // value may be a number or an array of numbers
39
- root.lessThan = function(value, max) {
40
- value = normalize(value);
41
- var matching = _.select(value, function(v) {return v<=max;});
42
- return matching.length;
43
- };
44
-
45
- // Returns true if any conditions[i].end is within the specified period,
46
- // false otherwise
47
- root.conditionResolved = function(conditions, startDate, endDate) {
48
- conditions = normalize(conditions);
49
- var resolvedWithinPeriod = function(condition) {
50
- return (condition.end>=startDate && condition.end<=endDate);
51
- };
52
- return _.any(conditions, resolvedWithinPeriod);
53
- };
54
-
55
- // Returns the minimum of readings[i].value where readings[i].date is in
56
- // the supplied startDate and endDate. If no reading meet this criteria,
57
- // returns defaultValue.
58
- root.minValueInDateRange = function(readings, startDate, endDate, defaultValue) {
59
- readings = normalize(readings);
60
-
61
- var readingInDateRange = function(reading) {
62
- return (reading.date>=startDate && reading.date<=endDate);
63
- };
64
-
65
- var allInDateRange = _.select(readings, readingInDateRange);
66
- if (allInDateRange.length==0)
67
- return defaultValue;
68
- var min = _.min(allInDateRange, function(reading) {return reading.value;});
69
- if (min==undefined)
70
- return defaultValue;
71
- return min.value;
72
- };
73
-
74
- // Returns the most recent readings[i].value where readings[i].date is in
75
- // the supplied startDate and endDate. If no reading meet this criteria,
76
- // returns defaultValue.
77
- root.latestValueInDateRange = function(readings, startDate, endDate, defaultValue) {
78
- readings = normalize(readings);
79
-
80
- var readingInDateRange = function(reading) {
81
- return (reading.date>=startDate && reading.date<=endDate);
82
- };
83
-
84
- var allInDateRange = _.select(readings, readingInDateRange);
85
- if (allInDateRange.length==0)
86
- return defaultValue;
87
- var latest = _.max(allInDateRange, function(reading) {return reading.date;});
88
- if (latest==undefined)
89
- return defaultValue;
90
- return latest.value;
91
- };
92
-
93
- // Returns the number of actions that occur within the specified time period of
94
- // something. The first two arguments are arrays or single-valued time stamps in
95
- // seconds-since-the-epoch, timePeriod is in seconds.
96
- root.actionFollowingSomething = function(something, action, timePeriod) {
97
- something = normalize(something);
98
- action = normalize(action);
99
- if (timePeriod===undefined)
100
- timePeriod=Infinity;
101
-
102
- var result = 0;
103
- for (i=0; i<something.length; i++) {
104
- var timeStamp = something[i];
105
- for (j=0; j<action.length;j++) {
106
- if (action[j]>=timeStamp && (action[j] <= (timeStamp+timePeriod)))
107
- result++;
108
- }
109
- }
110
-
111
- return result;
112
- }
113
-
114
- // Returns all members of the values array that fall between min and max inclusive
115
- root.selectWithinRange = function(values, min, max) {
116
- values = normalize(values);
117
- return _.select(values, function(value) { return value<=max && value>=min; });
118
- }
119
-
120
- // calculates the earliest birthdate for a maximum age given a target date.
121
- // calculation is inclusive of the full year for the target age
122
- // returns: (earliest birthdate that will reach by not exceed the age by the target date)
123
- // age: integer in years
124
- // effective_date: end of the measurement period, in seconds
125
- root.earliestBirthdayForThisAge = function(age, effective_date) {
126
- return calculateDateForAge(age, effective_date, true);
127
- }
128
- // calculates the latest birthdate for a minimum age given a target date
129
- // returns: (latest birthdate that will reach the age by the target date)
130
- // age: integer in years
131
- // effective_date: end of the measurement period, in seconds
132
- root.latestBirthdayForThisAge = function(age, effective_date) {
133
- return calculateDateForAge(age, effective_date, false);
134
- }
135
- // returns birth date for an age value given a specific date
136
- // age: integer in years
137
- // effective_date: end of the measurement period, in seconds
138
- // is_inclusive: boolean for including or excluding age
139
- root.calculateDateForAge = function(age, effective_date, is_inclusive) {
140
- var earliest_birthdate = new Date(effective_date*1000);
141
- var difference = age;
142
- if (is_inclusive) difference += 1;
143
- earliest_birthdate.setFullYear(earliest_birthdate.getFullYear()-difference);
144
- return earliest_birthdate.getTime()/1000;
145
- }
146
-
147
-
148
- root.map = function(record, population, denominator, numerator, exclusion) {
149
- var value = {population: false, denominator: false, numerator: false,
150
- exclusions: false, antinumerator: false, patient_id: record._id,
151
- medical_record_id: record.medical_record_number,
152
- first: record.first, last: record.last, gender: record.gender,
153
- birthdate: record.birthdate, test_id: record.test_id,
154
- provider_performances: record.provider_performances,
155
- race: record.race, ethnicity: record.ethnicity, languages: record.languages};
156
- if (population()) {
157
- value.population = true;
158
- if (denominator()) {
159
- value.denominator = true;
160
- if (numerator()) {
161
- value.numerator = true;
162
- } else if (exclusion()) {
163
- value.exclusions = true;
164
- value.denominator = false;
165
- } else {
166
- value.antinumerator = true;
167
- }
168
- }
169
- }
170
- emit(ObjectId(), value);
171
- };
172
-
173
- }