quality-measure-engine 1.1.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
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