class CqlMeasure

Constants

DEFAULT_EFFECTIVE_DATE
MP_START_DATE
TYPES

Public Class Methods

for_patient(record) click to toggle source

Find the measures matching a patient

# File lib/models/cql_measure.rb, line 67
def self.for_patient(record)
  where user_id: record.user_id, hqmf_set_id: { '$in' => record.measure_ids }
end

Public Instance Methods

all_data_criteria() click to toggle source
# File lib/models/cql_measure.rb, line 115
def all_data_criteria
  as_hqmf_model.all_data_criteria
end
as_hqmf_model() click to toggle source

Returns the hqmf-parser's ruby implementation of an HQMF document. Rebuild from population_criteria, data_criteria, and measure_period JSON

# File lib/models/cql_measure.rb, line 96
def as_hqmf_model
  json = {
    "id" => self.measure_id,
    "title" => self.title,
    "description" => self.description,
    "population_criteria" => self.population_criteria,
    "data_criteria" => self.data_criteria,
    "source_data_criteria" => self.source_data_criteria,
    "measure_period" => self.measure_period,
    "attributes" => self.measure_attributes,
    "populations" => self.populations,
    "hqmf_id" => self.hqmf_id,
    "hqmf_set_id" => self.hqmf_set_id,
    "hqmf_version_number" => self.hqmf_version_number,
    "cms_id" => self.cms_id
  }
  HQMF::Document.from_json(json)
end
calculate_complexity() click to toggle source
# File lib/models/cql_measure.rb, line 134
def calculate_complexity
  # We calculate the complexity for each statement, and (at least for now) store the result in the same way
  # we store the complexity for QDM variables
  # TODO: consider whether this is too much of a force fit
  self.complexity = { variables: [] }
  # Recursively look through an expression to count the logical branches
  def count_expression_logical_branches(expression)
    case expression
    when nil
      0
    when Array
      expression.map { |exp| count_expression_logical_branches(exp) }.sum
    when Hash
      case expression['type']
      when 'And', 'Or', 'Not'
        count_expression_logical_branches(expression['operand'])
      when 'Query'
        # TODO: Do we need to look into the source side of the query? Can there be logical operators there?
        count_expression_logical_branches(expression['where']) + count_expression_logical_branches(expression['relationship'])
      else
        1
      end
    else
      0
    end
  end

  # Determine the complexity of each statement
  self.elm.each do |elm|
    if statements = elm.try(:[], 'library').try(:[], 'statements').try(:[], 'def')
      statements.each do |statement|
        self.complexity[:variables] << { name: statement['name'], complexity: count_expression_logical_branches(statement['expression']) }
      end
    end
  end
  self.complexity
end
composite_hqmf_set_id() click to toggle source

Returns the composite measure's hqmf_set_id for this component Component measure hqmf_set_id is formatted as follows:

<composite_hqmf_set_id>&<component_hqmf_set_id>
# File lib/models/cql_measure.rb, line 175
def composite_hqmf_set_id
  self.hqmf_set_id.split("&")[0]
end
count_expression_logical_branches(expression) click to toggle source

Recursively look through an expression to count the logical branches

# File lib/models/cql_measure.rb, line 140
def count_expression_logical_branches(expression)
  case expression
  when nil
    0
  when Array
    expression.map { |exp| count_expression_logical_branches(exp) }.sum
  when Hash
    case expression['type']
    when 'And', 'Or', 'Not'
      count_expression_logical_branches(expression['operand'])
    when 'Query'
      # TODO: Do we need to look into the source side of the query? Can there be logical operators there?
      count_expression_logical_branches(expression['where']) + count_expression_logical_branches(expression['relationship'])
    else
      1
    end
  else
    0
  end
end
set_continuous_variable() click to toggle source
# File lib/models/cql_measure.rb, line 121
def set_continuous_variable
  # The return value of this function is not related to whether or not this
  # measure is a CV measure. The true return value ensures false is not
  # accidentally returned here, which would cause the chain of 'before_*' to
  # stop executing.
  self.continuous_variable = populations.map {|x| x.keys}.flatten.uniq.include? HQMF::PopulationCriteria::MSRPOPL
  true
end
value_sets() click to toggle source
# File lib/models/cql_measure.rb, line 71
def value_sets
  options = { oid: value_set_oids }
  options[:user_id] = user.id if user?
  @value_sets ||= HealthDataStandards::SVS::ValueSet.in(options)
  @value_sets
end
value_sets_by_oid() click to toggle source
# File lib/models/cql_measure.rb, line 78
def value_sets_by_oid
  @value_sets_by_oid = {}
  value_sets.each do |vs|
    if @value_sets_by_oid[vs.oid]
      # If there are multiple value sets with the same oid for the user, then keep the one with
      # the version corresponding to this measure.
      if vs.version.include?(hqmf_set_id)
        @value_sets_by_oid[vs.oid] = { vs.version => vs }
      end
    else
      @value_sets_by_oid[vs.oid] = { vs.version => vs }
    end
  end
  @value_sets_by_oid
end