Class: CqlMeasure

Inherits:
Object
  • Object
show all
Includes:
Mongoid::Attributes::Dynamic, Mongoid::Document, Mongoid::Timestamps
Defined in:
lib/models/cql_measure.rb

Constant Summary collapse

DEFAULT_EFFECTIVE_DATE =
Time.gm(2012,12,31,23,59).to_i
MP_START_DATE =
Time.gm(2012,1,1,0,0).to_i
TYPES =
["ep", "eh"]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.for_patient(record) ⇒ Object

Find the measures matching a patient



63
64
65
# File 'lib/models/cql_measure.rb', line 63

def self.for_patient(record)
  where user_id: record.user_id, hqmf_set_id: { '$in' => record.measure_ids }
end

Instance Method Details

#all_data_criteriaObject



95
96
97
# File 'lib/models/cql_measure.rb', line 95

def all_data_criteria
  as_hqmf_model.all_data_criteria
end

#as_hqmf_modelObject

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



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/models/cql_measure.rb', line 76

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_complexityObject



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/models/cql_measure.rb', line 114

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

#count_expression_logical_branches(expression) ⇒ Object

Recursively look through an expression to count the logical branches



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/models/cql_measure.rb', line 120

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_variableObject



101
102
103
104
105
106
107
108
# File 'lib/models/cql_measure.rb', line 101

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_setsObject



67
68
69
70
71
72
# File 'lib/models/cql_measure.rb', line 67

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