Class: QME::QualityReport

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

Overview

A class that allows you to create and obtain the results of running a quality measure against a set of patient records.

Constant Summary collapse

POPULATION =
'IPP'
DENOMINATOR =
'DENOM'
NUMERATOR =
'NUMER'
EXCLUSIONS =
'DENEX'
EXCEPTIONS =
'DENEXCEP'
MSRPOPL =
'MSRPOPL'
OBSERVATION =
'OBSERV'
ANTINUMERATOR =
'antinumerator'
CONSIDERED =
'considered'
RACE =
'RACE'
ETHNICITY =
'ETHNICITY'
SEX =
'SEX'
POSTAL_CODE =
'POSTAL_CODE'
PAYER =
'PAYER'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.find_or_create(measure_id, sub_id, parameter_values) ⇒ Object



94
95
96
97
98
99
100
# File 'lib/qme/quality_report.rb', line 94

def self.find_or_create(measure_id, sub_id, parameter_values)
  @parameter_values = parameter_values
  @parameter_values[:filters] = self.normalize_filters(@parameter_values[:filters])
  query = {measure_id: measure_id, sub_id: sub_id}
  query.merge! @parameter_values
  self.find_or_create_by(query)
end

.normalize_filters(filters) ⇒ Object

make sure all filter id arrays are sorted



173
174
175
# File 'lib/qme/quality_report.rb', line 173

def self.normalize_filters(filters)
  filters.each {|key, value| value.sort_by! {|v| (v.is_a? Hash) ? "#{v}" : v} if value.is_a? Array} unless filters.nil?
end

.queue_staged_rollups(measure_id, sub_id, effective_date) ⇒ Object



102
103
104
105
106
107
108
109
110
# File 'lib/qme/quality_report.rb', line 102

def self.queue_staged_rollups(measure_id,sub_id,effective_date)
 query = Mongoid.default_session["rollup_buffer"].find({measure_id: measure_id, sub_id: sub_id, effective_date: effective_date})
 query.each do |options|
    if QME::QualityReport.where("_id" => options["quality_report_id"]).count == 1
       QME::QualityReport.enque_job(options,:rollup)
    end
 end
 query.remove_all
end

.update_patient_results(id) ⇒ Object

Removes the cached results for the patient with the supplied id and recalculates as necessary



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/qme/quality_report.rb', line 64

def self.update_patient_results(id)
  # TODO: need to wait for any outstanding calculations to complete and then prevent
  # any new ones from starting until we are done.

  # drop any cached measure result calculations for the modified patient
 QME::PatientCache.where('value.medical_record_id' => id).destroy()

  # get a list of cached measure results for a single patient
  sample_patient = QME::PatientCache.where({}).first
  if sample_patient
    cached_results = QME::PatientCache.where({'value.patient_id' => sample_patient['value']['patient_id']})

    # for each cached result (a combination of measure_id, sub_id, effective_date and test_id)
    cached_results.each do |measure|
      # recalculate patient_cache value for modified patient
      value = measure['value']
      map = QME::MapReduce::Executor.new(value['measure_id'], value['sub_id'],
        'effective_date' => value['effective_date'], 'test_id' => value['test_id'])
      map.map_record_into_measure_groups(id)
    end
  end

  # remove the query totals so they will be recalculated using the new results for
  # the modified patient
  self.destroy_all
end

Instance Method Details

#calculate(parameters, asynchronous = true) ⇒ Object

Kicks off a background job to calculate the measure

Returns:

  • a unique id for the measure calculation job



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/qme/quality_report.rb', line 134

def calculate(parameters, asynchronous=true)

  options = {'quality_report_id' => self.id}
  options.merge! parameters || {}

  if self.status["state"] == "completed" && !options["recalculate"]
    return self
  end

  self.status["state"] = "queued"
  if (asynchronous)
    options[:asynchronous] = true
    if patients_cached?
      QME::QualityReport.enque_job(options,:rollup)
    elsif calculation_queued_or_running?
      self.status["state"] = "stagged"
      self.save
      options.merge!( {measure_id: self.measure_id, sub_id: self.sub_id, effective_date: self.effective_date })
      Mongoid.default_session["rollup_buffer"].insert(options)
    else
      # queue the job for calculation
      QME::QualityReport.enque_job(options,:calculation)
    end
  else
    mcj = QME::MapReduce::MeasureCalculationJob.new(options)
    mcj.perform
  end
end

#calculated?true|false

Determines whether the quality report has been calculated for the given measure and parameters

Returns:

  • (true|false)


115
116
117
# File 'lib/qme/quality_report.rb', line 115

def calculated?
  self.status["state"] == "completed"
end

#calculation_queued_or_running?Boolean

queued up by another quality report or if it is currently running

Returns:

  • (Boolean)


128
129
130
# File 'lib/qme/quality_report.rb', line 128

def calculation_queued_or_running?
  !QME::QualityReport.where({measure_id: self.measure_id,sub_id:self.sub_id, effective_date: self.effective_date, test_id: self.test_id }).nin("status.state" =>["unknown","stagged"]).first.nil?
end

#measureObject



168
169
170
# File 'lib/qme/quality_report.rb', line 168

def measure
  QME::QualityMeasure.where({"hqmf_id"=>self.measure_id, "sub_id" => self.sub_id}).first
end

#patient_cache_matcherObject



186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/qme/quality_report.rb', line 186

def patient_cache_matcher
  match = {'value.measure_id' => self.measure_id,
           'value.sub_id'           => self.sub_id,
           'value.effective_date'   => self.effective_date,
           'value.test_id'          => test_id,
           'value.manual_exclusion' => {'$in' => [nil, false]}}

  if(filters)
    if (filters['races'] && filters['races'].size > 0)
      match['value.race.code'] = {'$in' => filters['races']}
    end
    if (filters['ethnicities'] && filters['ethnicities'].size > 0)
      match['value.ethnicity.code'] = {'$in' => filters['ethnicities']}
    end
    if (filters['genders'] && filters['genders'].size > 0)
      match['value.gender'] = {'$in' => filters['genders']}
    end
    if (filters['providers'] && filters['providers'].size > 0)
      providers = filters['providers'].map { |pv| BSON::ObjectId.from_string(pv) }
      match['value.provider_performances.provider_id'] = {'$in' => providers}
    end
    if (filters['languages'] && filters['languages'].size > 0)
      match["value.languages"] = {'$in' => filters['languages']}
    end
  end
  match
end

#patient_result(patient_id = nil) ⇒ Object



177
178
179
180
181
182
183
# File 'lib/qme/quality_report.rb', line 177

def patient_result(patient_id = nil)
  query = patient_cache_matcher
  if patient_id
    query['value.medical_record_id'] = patient_id
  end
   QME::PatientCache.where(query).first()
end

#patient_resultsObject



163
164
165
166
# File 'lib/qme/quality_report.rb', line 163

def patient_results
 ex = QME::MapReduce::Executor.new(self.measure_id,self.sub_id, self.attributes)
 QME::PatientCache.where(patient_cache_matcher)
end

#patients_cached?Boolean

Determines whether the patient mapping for the quality report has been completed

Returns:

  • (Boolean)


121
122
123
# File 'lib/qme/quality_report.rb', line 121

def patients_cached?
  !QME::QualityReport.where({measure_id: self.measure_id,sub_id:self.sub_id, effective_date: self.effective_date, test_id: self.test_id, "status.state" => "completed" }).first.nil?
end