hqmf-parser 1.0.3 → 1.0.4
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 +1 -1
- data/lib/hqmf-generator/hqmf-generator.rb +1 -1
- data/lib/hqmf-model/document.rb +1 -1
- data/lib/hqmf-model/population_criteria.rb +4 -3
- data/lib/hqmf-parser/1.0/population_criteria.rb +1 -5
- data/lib/hqmf-parser/2.0/document.rb +1 -1
- data/lib/hqmf-parser/2.0/population_criteria.rb +1 -1
- data/lib/hqmf-parser/converter/pass1/data_criteria_converter.rb +6 -4
- data/lib/hqmf-parser/converter/pass1/document_converter.rb +1 -1
- data/lib/hqmf-parser/converter/pass1/population_criteria_converter.rb +7 -3
- data/lib/hqmf-parser/converter/pass1/simple_data_criteria.rb +1 -10
- metadata +2 -4
- data/lib/hqmf-parser/converter/pass3/specific_occurrence_converter.rb +0 -86
- data/lib/hqmf-parser/converter/pass3/specific_occurrence_converter_bak.rb +0 -70
data/Gemfile
CHANGED
@@ -7,7 +7,7 @@ gem 'nokogiri'
|
|
7
7
|
gem 'rubyzip'
|
8
8
|
|
9
9
|
#gem "health-data-standards", :git => 'http://github.com/projectcypress/health-data-standards.git', :branch => 'develop'
|
10
|
-
gem "health-data-standards", '~> 2.1.
|
10
|
+
gem "health-data-standards", '~> 2.1.3'
|
11
11
|
gem "bson_ext"
|
12
12
|
|
13
13
|
# below are gems required for excel spreadsheet processing
|
@@ -278,7 +278,7 @@ module HQMF2
|
|
278
278
|
'denominator'
|
279
279
|
when HQMF::PopulationCriteria::NUMER
|
280
280
|
'numerator'
|
281
|
-
when HQMF::PopulationCriteria::
|
281
|
+
when HQMF::PopulationCriteria::DENEXCEP
|
282
282
|
'denominatorException'
|
283
283
|
when HQMF::PopulationCriteria::DENEX
|
284
284
|
'denominatorExclusion'
|
data/lib/hqmf-model/document.rb
CHANGED
@@ -40,7 +40,7 @@ module HQMF
|
|
40
40
|
HQMF::PopulationCriteria::IPP => HQMF::PopulationCriteria::IPP,
|
41
41
|
HQMF::PopulationCriteria::DENOM => HQMF::PopulationCriteria::DENOM,
|
42
42
|
HQMF::PopulationCriteria::NUMER => HQMF::PopulationCriteria::NUMER,
|
43
|
-
HQMF::PopulationCriteria::
|
43
|
+
HQMF::PopulationCriteria::DENEXCEP => HQMF::PopulationCriteria::DENEXCEP,
|
44
44
|
HQMF::PopulationCriteria::DENEX => HQMF::PopulationCriteria::DENEX
|
45
45
|
}
|
46
46
|
]
|
@@ -10,10 +10,11 @@ module HQMF
|
|
10
10
|
IPP = 'IPP'
|
11
11
|
DENOM = 'DENOM'
|
12
12
|
NUMER = 'NUMER'
|
13
|
-
|
13
|
+
DENEXCEP = 'DENEXCEP'
|
14
14
|
DENEX = 'DENEX'
|
15
|
+
MSRPOPL = 'MSRPOPL'
|
15
16
|
|
16
|
-
ALL_POPULATION_CODES = [IPP, DENOM, NUMER,
|
17
|
+
ALL_POPULATION_CODES = [IPP, DENOM, NUMER, DENEXCEP, DENEX, MSRPOPL]
|
17
18
|
|
18
19
|
# Create a new population criteria
|
19
20
|
# @param [String] id
|
@@ -64,7 +65,7 @@ module HQMF
|
|
64
65
|
case @type
|
65
66
|
when IPP, DENOM, NUMER
|
66
67
|
HQMF::Precondition::ALL_TRUE
|
67
|
-
when
|
68
|
+
when DENEXCEP, DENEX
|
68
69
|
HQMF::Precondition::AT_LEAST_ONE_TRUE
|
69
70
|
else
|
70
71
|
raise "Unknown population type [#{@type}]"
|
@@ -24,7 +24,7 @@ module HQMF1
|
|
24
24
|
end
|
25
25
|
|
26
26
|
# Get the code for the population criteria
|
27
|
-
# @return [String] the code (e.g. IPP, DEMON, NUMER, DENEX,
|
27
|
+
# @return [String] the code (e.g. IPP, DEMON, NUMER, DENEX, DENEXCEP)
|
28
28
|
def code
|
29
29
|
value = attr_val('cda:observation/cda:value/@code')
|
30
30
|
# exclusion population criteria has id of DENOM with actionNegationInd of true
|
@@ -32,10 +32,6 @@ module HQMF1
|
|
32
32
|
if attr_val('cda:observation/@actionNegationInd')=='true'
|
33
33
|
value = HQMF::PopulationCriteria::DENEX
|
34
34
|
end
|
35
|
-
# replace measure population with NUMER. MSRPOPL is used in continuous variable calculations.
|
36
|
-
value = HQMF::PopulationCriteria::NUMER if value == 'MSRPOPL'
|
37
|
-
# replace DENEXCEP with EXCEP. DENEXCEP is used by the MAT instead of EXCEP as required by HQMF V2 and QRDA.
|
38
|
-
value = HQMF::PopulationCriteria::EXCEP if value == 'DENEXCEP'
|
39
35
|
value.upcase
|
40
36
|
end
|
41
37
|
|
@@ -57,7 +57,7 @@ module HQMF2
|
|
57
57
|
HQMF::PopulationCriteria::IPP => 'patientPopulationCriteria',
|
58
58
|
HQMF::PopulationCriteria::DENOM => 'denominatorCriteria',
|
59
59
|
HQMF::PopulationCriteria::NUMER => 'numeratorCriteria',
|
60
|
-
HQMF::PopulationCriteria::
|
60
|
+
HQMF::PopulationCriteria::DENEXCEP => 'denominatorExceptionCriteria',
|
61
61
|
HQMF::PopulationCriteria::DENEX => 'denominatorExclusionCriteria'
|
62
62
|
}.each_pair do |criteria_id, criteria_element_name|
|
63
63
|
criteria_def = population_def.at_xpath("cda:component[cda:#{criteria_element_name}]", NAMESPACES)
|
@@ -36,7 +36,7 @@ module HQMF2
|
|
36
36
|
case @type
|
37
37
|
when HQMF::PopulationCriteria::IPP, HQMF::PopulationCriteria::DENOM, HQMF::PopulationCriteria::NUMER
|
38
38
|
HQMF::Precondition::ALL_TRUE
|
39
|
-
when HQMF::PopulationCriteria::
|
39
|
+
when HQMF::PopulationCriteria::DENEXCEP, HQMF::PopulationCriteria::DENEX
|
40
40
|
HQMF::Precondition::AT_LEAST_ONE_TRUE
|
41
41
|
else
|
42
42
|
raise "Unknown population type [#{@type}]"
|
@@ -22,10 +22,6 @@ module HQMF
|
|
22
22
|
# the restrictions added may be different for the numerator, denominator, different IPP_1, IPP_2, etc.
|
23
23
|
def duplicate_data_criteria(data_criteria, parent_id)
|
24
24
|
|
25
|
-
# if this is a specific occurrence, then we do not want to duplicate it.
|
26
|
-
# we may need to duplicate it for a population however.
|
27
|
-
# return data_criteria if (specific_occurrences[data_criteria.id])
|
28
|
-
|
29
25
|
if (data_criteria.is_a? HQMF::Converter::SimpleDataCriteria and data_criteria.precondition_id == parent_id)
|
30
26
|
new_data_criteria = data_criteria
|
31
27
|
else
|
@@ -176,6 +172,12 @@ module HQMF
|
|
176
172
|
specific_occurrence = criteria[:specific_occurrence]
|
177
173
|
specific_occurrence_const = criteria[:specific_occurrence_const]
|
178
174
|
|
175
|
+
# specific occurrences do not properly set the description, so we want to add the definition and status
|
176
|
+
if (specific_occurrence)
|
177
|
+
_status = ", #{status.titleize}" if status
|
178
|
+
description = "#{definition.titleize}#{_status}: #{description}"
|
179
|
+
end
|
180
|
+
|
179
181
|
value = nil # value is filled out by backfill_patient_characteristics for things like gender and by REFR restrictions
|
180
182
|
effective_time = nil # filled out by temporal reference code
|
181
183
|
temporal_references = # filled out by operator code
|
@@ -169,7 +169,7 @@ module HQMF
|
|
169
169
|
|
170
170
|
oid_fields = document.all_data_criteria.select {|dc| dc.field_values != nil}
|
171
171
|
if oid_fields.size > 0
|
172
|
-
referenced_oids = (oid_fields.map{|dc| dc.field_values.map {|key,field| puts "field: #{key} is nil" unless field; field.code_list_id if field != nil and field.type == 'CD'}}).flatten.compact.uniq
|
172
|
+
referenced_oids = (oid_fields.map{|dc| dc.field_values.map {|key,field| puts "field: #{key} is nil" unless field || key.match(/DATETIME/); field.code_list_id if field != nil and field.type == 'CD'}}).flatten.compact.uniq
|
173
173
|
referenced_oids.each do |oid|
|
174
174
|
value_set = codes[oid]
|
175
175
|
puts "\tFIELDS (#{document.id},#{document.title}): referenced OID could not be found #{oid}" unless value_set
|
@@ -25,8 +25,9 @@ module HQMF
|
|
25
25
|
ipps = @population_criteria_by_id.select {|key, value| value.type == HQMF::PopulationCriteria::IPP}
|
26
26
|
denoms = @population_criteria_by_id.select {|key, value| value.type == HQMF::PopulationCriteria::DENOM}
|
27
27
|
nums = @population_criteria_by_id.select {|key, value| value.type == HQMF::PopulationCriteria::NUMER}
|
28
|
+
msrpopls = @population_criteria_by_id.select {|key, value| value.type == HQMF::PopulationCriteria::MSRPOPL}
|
28
29
|
excls = @population_criteria_by_id.select {|key, value| value.type == HQMF::PopulationCriteria::DENEX}
|
29
|
-
denexcs = @population_criteria_by_id.select {|key, value| value.type == HQMF::PopulationCriteria::
|
30
|
+
denexcs = @population_criteria_by_id.select {|key, value| value.type == HQMF::PopulationCriteria::DENEXCEP}
|
30
31
|
|
31
32
|
if (ipps.size<=1 and denoms.size<=1 and nums.size<=1 and excls.size<=1 and denexcs.size<=1 )
|
32
33
|
@sub_measures <<
|
@@ -34,7 +35,7 @@ module HQMF
|
|
34
35
|
HQMF::PopulationCriteria::IPP => HQMF::PopulationCriteria::IPP,
|
35
36
|
HQMF::PopulationCriteria::DENOM => HQMF::PopulationCriteria::DENOM,
|
36
37
|
HQMF::PopulationCriteria::NUMER => HQMF::PopulationCriteria::NUMER,
|
37
|
-
HQMF::PopulationCriteria::
|
38
|
+
HQMF::PopulationCriteria::DENEXCEP => HQMF::PopulationCriteria::DENEXCEP,
|
38
39
|
HQMF::PopulationCriteria::DENEX => HQMF::PopulationCriteria::DENEX
|
39
40
|
}
|
40
41
|
else
|
@@ -42,10 +43,13 @@ module HQMF
|
|
42
43
|
nums.each do |num_id, num|
|
43
44
|
@sub_measures << {HQMF::PopulationCriteria::NUMER => num.id}
|
44
45
|
end
|
46
|
+
msrpopls.each do |popl_id, popl|
|
47
|
+
@sub_measures << {HQMF::PopulationCriteria::MSRPOPL => popl.id}
|
48
|
+
end
|
45
49
|
apply_to_submeasures(@sub_measures, HQMF::PopulationCriteria::DENOM, denoms.values)
|
46
50
|
apply_to_submeasures(@sub_measures, HQMF::PopulationCriteria::IPP, ipps.values)
|
47
51
|
apply_to_submeasures(@sub_measures, HQMF::PopulationCriteria::DENEX, excls.values)
|
48
|
-
apply_to_submeasures(@sub_measures, HQMF::PopulationCriteria::
|
52
|
+
apply_to_submeasures(@sub_measures, HQMF::PopulationCriteria::DENEXCEP, denexcs.values)
|
49
53
|
|
50
54
|
keep = []
|
51
55
|
@sub_measures.each do |sub|
|
@@ -7,9 +7,7 @@ module HQMF
|
|
7
7
|
attr_accessor :precondition_id
|
8
8
|
|
9
9
|
def self.from_data_criteria(data_criteria)
|
10
|
-
description
|
11
|
-
|
12
|
-
HQMF::Converter::SimpleDataCriteria.new(data_criteria.id, data_criteria.title, data_criteria.display_name, description, data_criteria.code_list_id,
|
10
|
+
HQMF::Converter::SimpleDataCriteria.new(data_criteria.id, data_criteria.title, data_criteria.display_name, data_criteria.description, data_criteria.code_list_id,
|
13
11
|
data_criteria.children_criteria, data_criteria.derivation_operator, data_criteria.definition,data_criteria.status, data_criteria.value, data_criteria.field_values,
|
14
12
|
data_criteria.effective_time, data_criteria.inline_code_list,data_criteria.negation,data_criteria.negation_code_list_id,data_criteria.temporal_references, data_criteria.subset_operators, data_criteria.specific_occurrence,data_criteria.specific_occurrence_const)
|
15
13
|
end
|
@@ -21,13 +19,6 @@ module HQMF
|
|
21
19
|
@id = "#{@id}_precondition_#{precondtion_id}"
|
22
20
|
end
|
23
21
|
|
24
|
-
def self.get_description(data_criteria)
|
25
|
-
description = data_criteria.description
|
26
|
-
status = ", #{data_criteria.status.titleize}" if data_criteria.status
|
27
|
-
description = "#{data_criteria.definition.titleize}#{status}: #{data_criteria.description}" if (data_criteria.description.downcase.match /#{data_criteria.definition.titleize.downcase}/).nil? and (data_criteria.description.downcase.match /#{data_criteria.status}/).nil?
|
28
|
-
description
|
29
|
-
end
|
30
|
-
|
31
22
|
end
|
32
23
|
end
|
33
24
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hqmf-parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-11-
|
14
|
+
date: 2012-11-14 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rubyzip
|
@@ -119,8 +119,6 @@ files:
|
|
119
119
|
- lib/hqmf-parser/converter/pass1/simple_restriction.rb
|
120
120
|
- lib/hqmf-parser/converter/pass2/comparison_converter.rb
|
121
121
|
- lib/hqmf-parser/converter/pass2/operator_converter.rb
|
122
|
-
- lib/hqmf-parser/converter/pass3/specific_occurrence_converter.rb
|
123
|
-
- lib/hqmf-parser/converter/pass3/specific_occurrence_converter_bak.rb
|
124
122
|
- lib/hqmf-parser/parser.rb
|
125
123
|
- lib/hqmf-parser/value_sets/value_set_parser.rb
|
126
124
|
- lib/hqmf-parser.rb
|
@@ -1,86 +0,0 @@
|
|
1
|
-
module HQMF
|
2
|
-
# Class for cleaning up references to specific occurrences in the tree
|
3
|
-
class SpecificOccurrenceConverter
|
4
|
-
|
5
|
-
def initialize(data_criteria_converter)
|
6
|
-
@data_criteria_converter = data_criteria_converter
|
7
|
-
end
|
8
|
-
|
9
|
-
def convert_specific_occurrences(population_criteria)
|
10
|
-
population_criteria.each do |population|
|
11
|
-
walk_up_tree(population.preconditions)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def walk_up_tree(preconditions)
|
16
|
-
preconditions.each do |precondition|
|
17
|
-
if (has_child_comparison(precondition))
|
18
|
-
walk_up_tree(precondition.preconditions)
|
19
|
-
end
|
20
|
-
unless (precondition.comparison?)
|
21
|
-
occurrence_map = get_grouped_occurrences(precondition.preconditions)
|
22
|
-
occurrence_map.each do |key, value|
|
23
|
-
|
24
|
-
##
|
25
|
-
##### figure out negations
|
26
|
-
##
|
27
|
-
|
28
|
-
if (precondition.conjunction_code == 'atLeastOneTrue')
|
29
|
-
|
30
|
-
group = @data_criteria_converter.build_group_data_criteria(value, "#{key}_union", precondition.id, HQMF::DataCriteria::UNION)
|
31
|
-
binding.pry
|
32
|
-
elsif (precondition.conjunction_code == 'allTrue')
|
33
|
-
binding.pry
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def get_grouped_occurrences(preconditions)
|
42
|
-
|
43
|
-
result = {}
|
44
|
-
preconditions.each do |precondition|
|
45
|
-
if (precondition.preconditions and !precondition.preconditions.empty?)
|
46
|
-
get_grouped_occurrences(precondition.preconditions).each do |key, value|
|
47
|
-
if (result[key])
|
48
|
-
result[key].concat(value)
|
49
|
-
else
|
50
|
-
result[key] = value
|
51
|
-
end
|
52
|
-
end
|
53
|
-
else
|
54
|
-
data_criteria = @data_criteria_converter.v2_data_criteria_by_id[precondition.reference.id]
|
55
|
-
if is_specific_occurrence(data_criteria)
|
56
|
-
binding.pry
|
57
|
-
result[data_criteria.source_data_criteria] ||= []
|
58
|
-
result[data_criteria.source_data_criteria] << data_criteria
|
59
|
-
preconditions.delete(precondition)
|
60
|
-
binding.pry
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
result
|
65
|
-
|
66
|
-
end
|
67
|
-
|
68
|
-
def is_specific_occurrence(data_criteria)
|
69
|
-
!data_criteria.specific_occurrence.nil?
|
70
|
-
end
|
71
|
-
|
72
|
-
def has_child_comparison(node)
|
73
|
-
value = false
|
74
|
-
node.preconditions.each do |precondition|
|
75
|
-
if (precondition.comparison?)
|
76
|
-
value ||= true
|
77
|
-
elsif precondition.has_preconditions?
|
78
|
-
value ||= has_child_comparison(precondition)
|
79
|
-
end
|
80
|
-
end if node.preconditions
|
81
|
-
value
|
82
|
-
end
|
83
|
-
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
module HQMF
|
2
|
-
# Class for cleaning up references to specific occurrences in the tree
|
3
|
-
class SpecificOccurrenceConverter
|
4
|
-
|
5
|
-
def initialize(data_criteria_converter)
|
6
|
-
@data_criteria_converter = data_criteria_converter
|
7
|
-
end
|
8
|
-
|
9
|
-
def convert_specific_occurrences(population_criteria)
|
10
|
-
create_precondition_map(population_criteria)
|
11
|
-
|
12
|
-
@specific_occurrence_key_mapper = {}
|
13
|
-
|
14
|
-
specific_occurrences = {}
|
15
|
-
@data_criteria_converter.v2_data_criteria.each do |data_criteria|
|
16
|
-
if (is_specific_occurrence(data_criteria))
|
17
|
-
if (data_criteria.respond_to? :precondition_id and @precondition_map[data_criteria.precondition_id])
|
18
|
-
specific_occurrences[data_criteria.source_data_criteria] ||= []
|
19
|
-
specific_occurrences[data_criteria.source_data_criteria] << data_criteria
|
20
|
-
elsif (data_criteria.children_criteria or data_criteria.subset_operators or data_criteria.temporal_references)
|
21
|
-
binding.pry
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
specific_occurrences.each do |key, occurrences|
|
26
|
-
|
27
|
-
occurrences.sort! do |left, right|
|
28
|
-
@precondition_map[right.precondition_id].depth <=> @precondition_map[left.precondition_id].depth
|
29
|
-
end
|
30
|
-
|
31
|
-
occurrences.each_cons(2) do |pair|
|
32
|
-
parent = get_common_parent(@precondition_map[pair[0].precondition_id], @precondition_map[pair[1].precondition_id])
|
33
|
-
binding.pry
|
34
|
-
end
|
35
|
-
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def get_common_parent(left, right)
|
40
|
-
return left if left == right
|
41
|
-
get_common_parent(@precondition_parent_map[left.id], @precondition_parent_map[right.id])
|
42
|
-
end
|
43
|
-
|
44
|
-
def create_precondition_map(population_criteria)
|
45
|
-
@precondition_map = {}
|
46
|
-
@precondition_parent_map = {}
|
47
|
-
depth = 0
|
48
|
-
population_criteria.each do |population|
|
49
|
-
recurse_precondition_map(population, depth)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def recurse_precondition_map(node, depth)
|
54
|
-
node.preconditions.each do |precondition|
|
55
|
-
precondition.depth = depth
|
56
|
-
@precondition_map[precondition.id] = precondition
|
57
|
-
@precondition_parent_map[precondition.id] = node
|
58
|
-
if precondition.has_preconditions?
|
59
|
-
depth += 1
|
60
|
-
recurse_precondition_map(precondition, depth)
|
61
|
-
end
|
62
|
-
end if node.preconditions
|
63
|
-
end
|
64
|
-
|
65
|
-
def is_specific_occurrence(data_criteria)
|
66
|
-
!data_criteria.specific_occurrence.nil?
|
67
|
-
end
|
68
|
-
|
69
|
-
end
|
70
|
-
end
|