Class: HQMF2CQL::DocumentPopulationHelper

Inherits:
HQMF2::DocumentPopulationHelper show all
Includes:
HQMF2::Utilities
Defined in:
lib/hqmf-parser/cql/document_helpers/doc_population_helper.rb

Overview

Handles generation of populations for the main document

Instance Method Summary collapse

Methods included from HQMF2::Utilities

#attr_val, attr_val, #strip_tokens, #to_xml

Methods included from HQMF::Conversion::Utilities

#build_hash, #check_equality, #json_array, #openstruct_to_json

Methods inherited from HQMF2::DocumentPopulationHelper

#build_population_criteria, #extract_populations_and_criteria, #handle_base_populations, #initialize, #population_id_with_counter, #remove_population_preconditions

Constructor Details

This class inherits a constructor from HQMF2::DocumentPopulationHelper

Instance Method Details

#extract_main_libraryObject

Extracts the name of the main cql library from the Population Criteria Section.



111
112
113
114
115
116
117
118
119
120
121
# File 'lib/hqmf-parser/cql/document_helpers/doc_population_helper.rb', line 111

def extract_main_library
  population_criteria_sections = @doc.xpath("//cda:populationCriteriaSection/cda:component[@typeCode='COMP']", HQMF2::Document::NAMESPACES)
  criteria_section = population_criteria_sections.at_xpath("cda:initialPopulationCriteria", HQMF2::Document::NAMESPACES)
  if criteria_section
    # Example: the full name for the population criteria section is "BonnieNesting01.\"Initial Population\""
    # The regex returns everything before the "."  (BonnieNesting01), which is the file name of the cql measure
    cql_main_library_name = criteria_section.at_xpath("*/*/cda:id", HQMF2::Document::NAMESPACES).attribute('extension').to_s.match(/[^.]*/).to_s
  else
    nil
  end
end

#extract_observationsObject

Extracts potential measure observations from the CQL based HQMF. This function needs to return a boolean so that it will continue to work with HQMF2::DocumentPopulationHelper::extract_populations_and_criteria This function is being overridden because in CQL the observations are no longer data criteria in the HQMF.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/hqmf-parser/cql/document_helpers/doc_population_helper.rb', line 17

def extract_observations
  @observations = []

  # Look for observations in the measureObservationSection of the CQL based HQMF document, and if they exist extract the name of the CQL statement that calculates the observation. This is the name of the "define function" statement in the CQL.
  # In addition to the function name we also need to retreive the parameter for the function.
  observation_section = @doc.xpath('/cda:QualityMeasureDocument/cda:component/cda:measureObservationSection',
                                   HQMF2::Document::NAMESPACES)
  unless observation_section.empty?
    observation_section.each do |entry|
      # Need to add population criteria for observations
      criteria_id = 'OBSERV'
      criteria = HQMF2::PopulationCriteria.new(entry.xpath('cda:definition'), @document, @id_generator)
      criteria.type = 'OBSERV'
      if @ids_by_hqmf_id["#{criteria.hqmf_id}"]
        criteria.create_human_readable_id(@ids_by_hqmf_id[criteria.hqmf_id])
      else
        criteria.create_human_readable_id(population_id_with_counter(criteria_id))
        @ids_by_hqmf_id["#{criteria.hqmf_id}"] = criteria.id
      end
      @population_criteria << criteria

      # Extract CQL function specific details
      cql_define_function = {}
      # The at_xpath(...).values returns an array of a single element.
      # The match returns an array and since we don't want the double quotes we take the second element
      cql_define_function[:function_name] = entry.at_xpath("*/cda:measureObservationDefinition/cda:value/cda:expression").values.first.match('\\"([A-Za-z0-9 ]+)\\"')[1]
      cql_define_function[:parameter] = entry.at_xpath("*/cda:measureObservationDefinition/cda:component/cda:criteriaReference/cda:id").attributes['extension'].value.match('\\"([A-Za-z0-9 ]+)\\"')[1]
      @observations << cql_define_function
    end
  end
  !@observations.empty?
end

#extract_populationsObject



6
7
8
9
10
11
# File 'lib/hqmf-parser/cql/document_helpers/doc_population_helper.rb', line 6

def extract_populations
  @populations_cql_map = extract_populations_cql_map
  extract_populations_and_criteria
  # Return via destructuring
  [@populations, @population_criteria, @populations_cql_map, @observations]
end

#extract_populations_cql_mapObject

Extracts the mappings between actual HQMF populations and their corresponding CQL define statements.



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/hqmf-parser/cql/document_helpers/doc_population_helper.rb', line 79

def extract_populations_cql_map
  populations_cql_map = {}
  @doc.xpath("//cda:populationCriteriaSection/cda:component[@typeCode='COMP']", HQMF2::Document::NAMESPACES).each do |population_def|
    {
      HQMF::PopulationCriteria::IPP => 'initialPopulationCriteria',
      HQMF::PopulationCriteria::DENOM => 'denominatorCriteria',
      HQMF::PopulationCriteria::NUMER => 'numeratorCriteria',
      HQMF::PopulationCriteria::NUMEX => 'numeratorExclusionCriteria',
      HQMF::PopulationCriteria::DENEXCEP => 'denominatorExceptionCriteria',
      HQMF::PopulationCriteria::DENEX => 'denominatorExclusionCriteria',
      HQMF::PopulationCriteria::MSRPOPL => 'measurePopulationCriteria',
      HQMF::PopulationCriteria::MSRPOPLEX => 'measurePopulationExclusionCriteria',
      HQMF::PopulationCriteria::STRAT => 'stratifierCriteria'
    }.each_pair do |criteria_id, criteria_element_name|
      criteria_def = population_def.at_xpath("cda:#{criteria_element_name}", HQMF2::Document::NAMESPACES)
      if criteria_def
        # Ignore Supplemental Data Elements
        next if HQMF::PopulationCriteria::STRAT == criteria_id &&
            !criteria_def.xpath("cda:component[@typeCode='COMP']/cda:measureAttribute/cda:code[@code='SDE']").empty?
        cql_statement = criteria_def.at_xpath("*/*/cda:id", HQMF2::Document::NAMESPACES).attribute('extension').to_s.match(/"([^"]*)"/)
        if populations_cql_map[criteria_id].nil?
          populations_cql_map[criteria_id] = []
        end
        cql_statement = cql_statement.to_s.delete('\\"')
        populations_cql_map[criteria_id].push cql_statement
      end
    end
  end
  populations_cql_map
end

#handle_stratifications(population_def, number_of_populations, population, id_def, population_index) ⇒ Object

Generate the stratifications of populations, if any exist for CQL, adds ‘population_index’ and ‘stratification_index’



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/hqmf-parser/cql/document_helpers/doc_population_helper.rb', line 52

def handle_stratifications(population_def, number_of_populations, population, id_def, population_index)
  # handle stratifications (EP137, EP155)
  stratifier_criteria_xpath = "cda:component/cda:stratifierCriteria[not(cda:component/cda:measureAttribute/cda:code[@code  = 'SDE'])]/.."
  population_def.xpath(stratifier_criteria_xpath, HQMF2::Document::NAMESPACES)
    .each_with_index do |criteria_def, criteria_def_index|
    # Skip this Stratification if any precondition doesn't contain any preconditions
    next unless HQMF2::PopulationCriteria.new(criteria_def, @document, @id_generator)
                .preconditions.all? { |prcn| prcn.preconditions.length > 0 }
    index = number_of_populations + ((population_index - 1) * criteria_def.xpath('./*/cda:precondition').length) +
            criteria_def_index
    criteria_id = HQMF::PopulationCriteria::STRAT
    stratified_population = population.dup
    stratified_population['stratification'] = criteria_def.at_xpath('./*/cda:id/@root').try(:value) ||
                                              "#{criteria_id}-#{criteria_def_index}"
    build_population_criteria(criteria_def, criteria_id, stratified_population)

    stratified_population['id'] = id_def ? "#{id_def.value} - Stratification #{criteria_def_index + 1}" : "Population#{index}"
    title_def = population_def.at_xpath('cda:title/@value', HQMF2::Document::NAMESPACES)
    stratified_population['title'] = title_def ? "#{title_def.value} - Stratification #{criteria_def_index + 1}" : "Population #{index}"
    stratified_population['population_index'] = population_index
    stratified_population['stratification_index'] = criteria_def_index
    @stratifications << stratified_population
  end
end