quality-measure-engine 1.1.0 → 1.1.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.
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ gem 'bson_ext', '1.5.1', :platforms => :mri
7
7
  gem 'rake'
8
8
  #gem 'pry', :require => true
9
9
  #gem 'health-data-standards', :git => 'https://github.com/projectcypress/health-data-standards.git', :branch => 'master'
10
- gem 'health-data-standards', '0.7.0'
10
+ gem 'health-data-standards', '0.7.1'
11
11
 
12
12
  group :test do
13
13
  gem 'cover_me', '>= 1.0.0.rc5', :platforms => :ruby_19
@@ -116,7 +116,35 @@ function() {
116
116
  values = normalize(values);
117
117
  return _.select(values, function(value) { return value<=max && value>=min; });
118
118
  }
119
-
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
+
120
148
  root.map = function(record, population, denominator, numerator, exclusion) {
121
149
  var value = {population: false, denominator: false, numerator: false,
122
150
  exclusions: false, antinumerator: false, patient_id: record._id,
@@ -22,7 +22,6 @@ require_relative 'qme/ext/record'
22
22
 
23
23
  require_relative 'qme/importer/property_matcher'
24
24
  require_relative 'qme/importer/generic_importer'
25
- require_relative 'qme/importer/provider_importer'
26
25
  require_relative 'qme/importer/measure_properties_generator'
27
26
 
28
27
  require 'json'
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: 1.1.0
4
+ version: 1.1.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,12 +11,12 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2012-01-31 00:00:00.000000000 -05:00
14
+ date: 2012-02-17 00:00:00.000000000 -05:00
15
15
  default_executable:
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: mongo
19
- requirement: &2151835920 !ruby/object:Gem::Requirement
19
+ requirement: &2157284660 !ruby/object:Gem::Requirement
20
20
  none: false
21
21
  requirements:
22
22
  - - ~>
@@ -24,10 +24,10 @@ dependencies:
24
24
  version: '1.3'
25
25
  type: :runtime
26
26
  prerelease: false
27
- version_requirements: *2151835920
27
+ version_requirements: *2157284660
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: rubyzip
30
- requirement: &2151831040 !ruby/object:Gem::Requirement
30
+ requirement: &2157272260 !ruby/object:Gem::Requirement
31
31
  none: false
32
32
  requirements:
33
33
  - - ~>
@@ -35,10 +35,10 @@ dependencies:
35
35
  version: 0.9.4
36
36
  type: :runtime
37
37
  prerelease: false
38
- version_requirements: *2151831040
38
+ version_requirements: *2157272260
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: nokogiri
41
- requirement: &2151826060 !ruby/object:Gem::Requirement
41
+ requirement: &2157271520 !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
44
44
  - - ~>
@@ -46,10 +46,10 @@ dependencies:
46
46
  version: 1.4.4
47
47
  type: :runtime
48
48
  prerelease: false
49
- version_requirements: *2151826060
49
+ version_requirements: *2157271520
50
50
  - !ruby/object:Gem::Dependency
51
51
  name: resque
52
- requirement: &2151821480 !ruby/object:Gem::Requirement
52
+ requirement: &2157270840 !ruby/object:Gem::Requirement
53
53
  none: false
54
54
  requirements:
55
55
  - - ~>
@@ -57,10 +57,10 @@ dependencies:
57
57
  version: 1.15.0
58
58
  type: :runtime
59
59
  prerelease: false
60
- version_requirements: *2151821480
60
+ version_requirements: *2157270840
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: resque-status
63
- requirement: &2151818440 !ruby/object:Gem::Requirement
63
+ requirement: &2157270100 !ruby/object:Gem::Requirement
64
64
  none: false
65
65
  requirements:
66
66
  - - ~>
@@ -68,10 +68,10 @@ dependencies:
68
68
  version: 0.2.3
69
69
  type: :runtime
70
70
  prerelease: false
71
- version_requirements: *2151818440
71
+ version_requirements: *2157270100
72
72
  - !ruby/object:Gem::Dependency
73
73
  name: jsonschema
74
- requirement: &2151815160 !ruby/object:Gem::Requirement
74
+ requirement: &2157269380 !ruby/object:Gem::Requirement
75
75
  none: false
76
76
  requirements:
77
77
  - - ~>
@@ -79,10 +79,10 @@ dependencies:
79
79
  version: 2.0.0
80
80
  type: :development
81
81
  prerelease: false
82
- version_requirements: *2151815160
82
+ version_requirements: *2157269380
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
- requirement: &2151812380 !ruby/object:Gem::Requirement
85
+ requirement: &2157268580 !ruby/object:Gem::Requirement
86
86
  none: false
87
87
  requirements:
88
88
  - - ~>
@@ -90,10 +90,10 @@ dependencies:
90
90
  version: 2.5.0
91
91
  type: :development
92
92
  prerelease: false
93
- version_requirements: *2151812380
93
+ version_requirements: *2157268580
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: awesome_print
96
- requirement: &2151808480 !ruby/object:Gem::Requirement
96
+ requirement: &2157268080 !ruby/object:Gem::Requirement
97
97
  none: false
98
98
  requirements:
99
99
  - - ~>
@@ -101,10 +101,10 @@ dependencies:
101
101
  version: '0.3'
102
102
  type: :development
103
103
  prerelease: false
104
- version_requirements: *2151808480
104
+ version_requirements: *2157268080
105
105
  - !ruby/object:Gem::Dependency
106
106
  name: roo
107
- requirement: &2151800000 !ruby/object:Gem::Requirement
107
+ requirement: &2157267620 !ruby/object:Gem::Requirement
108
108
  none: false
109
109
  requirements:
110
110
  - - ~>
@@ -112,10 +112,10 @@ dependencies:
112
112
  version: 1.9.3
113
113
  type: :development
114
114
  prerelease: false
115
- version_requirements: *2151800000
115
+ version_requirements: *2157267620
116
116
  - !ruby/object:Gem::Dependency
117
117
  name: builder
118
- requirement: &2151803680 !ruby/object:Gem::Requirement
118
+ requirement: &2157267100 !ruby/object:Gem::Requirement
119
119
  none: false
120
120
  requirements:
121
121
  - - ~>
@@ -123,10 +123,10 @@ dependencies:
123
123
  version: 3.0.0
124
124
  type: :development
125
125
  prerelease: false
126
- version_requirements: *2151803680
126
+ version_requirements: *2157267100
127
127
  - !ruby/object:Gem::Dependency
128
128
  name: spreadsheet
129
- requirement: &2151912800 !ruby/object:Gem::Requirement
129
+ requirement: &2157266420 !ruby/object:Gem::Requirement
130
130
  none: false
131
131
  requirements:
132
132
  - - ~>
@@ -134,10 +134,10 @@ dependencies:
134
134
  version: 0.6.5.2
135
135
  type: :development
136
136
  prerelease: false
137
- version_requirements: *2151912800
137
+ version_requirements: *2157266420
138
138
  - !ruby/object:Gem::Dependency
139
139
  name: google-spreadsheet-ruby
140
- requirement: &2152185860 !ruby/object:Gem::Requirement
140
+ requirement: &2157265900 !ruby/object:Gem::Requirement
141
141
  none: false
142
142
  requirements:
143
143
  - - ~>
@@ -145,7 +145,7 @@ dependencies:
145
145
  version: 0.1.2
146
146
  type: :development
147
147
  prerelease: false
148
- version_requirements: *2152185860
148
+ version_requirements: *2157265900
149
149
  description: A library for extracting quality measure information from HITSP C32's
150
150
  and ASTM CCR's
151
151
  email: talk@projectpophealth.org
@@ -159,7 +159,6 @@ files:
159
159
  - lib/qme/importer/generic_importer.rb
160
160
  - lib/qme/importer/measure_properties_generator.rb
161
161
  - lib/qme/importer/property_matcher.rb
162
- - lib/qme/importer/provider_importer.rb
163
162
  - lib/qme/map/map_reduce_builder.rb
164
163
  - lib/qme/map/map_reduce_executor.rb
165
164
  - lib/qme/map/measure_calculation_job.rb
@@ -1,97 +0,0 @@
1
- require "date"
2
- require "date/delta"
3
-
4
- module QME
5
- module Importer
6
- class ProviderImporter
7
- include Singleton
8
-
9
- # Extract Healthcare Providers from C32
10
- #
11
- # @param [Nokogiri::XML::Document] doc It is expected that the root node of this document
12
- # will have the "cda" namespace registered to "urn:hl7-org:v3"
13
- # @return [Array] an array of providers found in the document
14
- def extract_providers(doc, use_encounters=false)
15
-
16
-
17
- xpath_base = use_encounters ? "//cda:encounter/cda:performer" : "//cda:documentationOf/cda:serviceEvent/cda:performer"
18
-
19
- performers = doc.xpath(xpath_base)
20
-
21
- providers = performers.map do |performer|
22
- provider = {}
23
- entity = performer.xpath(performer, "./cda:assignedEntity")
24
- name = entity.xpath("./cda:assignedPerson/cda:name")
25
- provider[:title] = extract_data(name, "./cda:prefix")
26
- provider[:given_name] = extract_data(name, "./cda:given[1]")
27
- provider[:family_name] = extract_data(name, "./cda:family")
28
- provider[:phone] = extract_data(entity, "./cda:telecom/@value") { |text| text.gsub("tel:", "") }
29
- provider[:organization] = extract_data(entity, "./cda:representedOrganization/cda:name")
30
- provider[:specialty] = extract_data(entity, "./cda:code/@code")
31
- time = performer.xpath(performer, "./cda:time")
32
- provider[:start] = extract_date(time, "./cda:low/@value")
33
- provider[:end] = extract_date(time, "./cda:high/@value")
34
- # NIST sample C32s use different OID for NPI vs C83, support both
35
- npi = extract_data(entity, "./cda:id[@root='2.16.840.1.113883.4.6' or @root='2.16.840.1.113883.3.72.5.2']/@extension")
36
- if ProviderImporter::valid_npi?(npi)
37
- provider[:npi] = npi
38
- else
39
- puts "Warning: Invalid NPI (#{npi})"
40
- end
41
- provider
42
- end
43
- end
44
-
45
- private
46
-
47
- def extract_date(subject,query)
48
- date = extract_data(subject,query)
49
- date ? Date.parse(date).to_time.to_i : nil
50
- end
51
-
52
- # Returns nil if result is an empty string, block allows text munging of result if there is one
53
- def extract_data(subject, query)
54
- result = subject.xpath(query).text
55
- if result == ""
56
- nil
57
- elsif block_given?
58
- yield(result)
59
- else
60
- result
61
- end
62
- end
63
-
64
- # validate the NPI, should be 10 or 15 digits total with the final digit being a
65
- # checksum using the Luhn algorithm with additional special handling as described in
66
- # https://www.cms.gov/NationalProvIdentStand/Downloads/NPIcheckdigit.pdf
67
- def self.valid_npi?(npi)
68
- return false if npi.length != 10 and npi.length != 15
69
- return false if npi.gsub(/\d/, '').length > 0 # npi must be all digits
70
- return false if npi.length == 15 and (npi =~ /^80840/)==nil # 15 digit npi must start with 80840
71
-
72
- # checksum is always calculated as if 80840 prefix is present
73
- if npi.length==10
74
- npi = '80840'+npi
75
- end
76
-
77
- return luhn_checksum(npi[0,14])==npi[14]
78
- end
79
-
80
- def self.luhn_checksum(num)
81
- double = {'0' => 0, '1' => 2, '2' => 4, '3' => 6, '4' => 8, '5' => 1, '6' => 3, '7' => 5, '8' => 7, '9' => 9}
82
- sum = 0
83
- num.reverse!
84
- num.split("").each_with_index do |char, i|
85
- if (i%2)==0
86
- sum+=double[char]
87
- else
88
- sum+=char.to_i
89
- end
90
- end
91
- sum = (9*sum)%10
92
-
93
- return sum.to_s
94
- end
95
- end
96
- end
97
- end