Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ami packer changes #1821

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions app/views/products/_product_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,6 @@
<% end %>
</fieldset>

<fieldset id="certification_edition">
<legend class="control-label">Certification Edition</legend>
<div class="radio">
<%= f.form_group :cert_edition, help: "Select the certification edition." do %>
<%= f.radio_button :cures_update, "false",
label: "2015 Edition",
label_class: "btn btn-checkbox",
disabled: [email protected]_record?,
checked: [email protected]_update %>
<%= f.radio_button :cures_update, "true",
label: "2015 Edition Cures Update",
label_class: "btn btn-checkbox",
disabled: [email protected]_record?,
checked: @product.cures_update %>
<% end # form_group %>
</div>
</fieldset>

<fieldset id="certification_options">
<legend class="control-label">Certification Types</legend>
<div id="certifications_errors_container"></div>
Expand Down
6 changes: 5 additions & 1 deletion app/views/records/_risk_variable_display.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
<% end %>
<% end %>
<% else %>
<ul><%= "Encounter #{encounter_ids.index(encounter_id) + 1}"%> <%= " - #{values}" if values != 'Encounter, Performed' %></ul>
<% if encounter_id == "Other" %>
<ul><%= values%></ul>
<% else %>
<ul><%= "Encounter #{encounter_ids.index(encounter_id) + 1}"%> <%= " - #{values}" if values != 'Encounter, Performed' %></ul>
<% end %>
<% end %>
<% end %>
</ul>
Expand Down
20 changes: 20 additions & 0 deletions config/cms_ig.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ CMS Programs:
- MIPS_APP1_APMENTITY
- MIPS_SUBGROUP
- PCF
'2023':
- MIPS_GROUP
- MIPS_INDIV
- MIPS_VIRTUALGROUP
- MIPS_APMENTITY
- MIPS_APP1_INDIV
- MIPS_APP1_GROUP
- MIPS_APP1_APMENTITY
- MIPS_SUBGROUP
- PCF
eh:
'2020':
- HQR_PI
Expand All @@ -45,6 +55,11 @@ CMS Programs:
- HQR_IQR
- HQR_PI_IQR
- HQR_OQR
'2023':
- HQR_PI
- HQR_IQR
- HQR_PI_IQR
- HQR_OQR
Program Specific Measures:
PCF:
# CMS122v9, CMS130v9, CMS165v9
Expand All @@ -62,6 +77,11 @@ Program Specific Measures:
[ '2C928085-7B2A-EB52-017B-56761E0218D0',
'2C928083-7ACE-2267-017B-11FBB9C913C4',
'2C928082-7A14-D92C-017A-67B6F9971EA8']
# CMS122v12, CMS130v12, CMS165v12
'2023':
[ '2C928084-83D3-1B44-0183-EB75DC8A03DB',
'2C928084-82EA-D7C5-0183-6BF2944520DC',
'2C928085-806C-39A2-0180-7092FA9B0145']
Program Criterion:
CCN:
name: 'CMS Certification Number'
Expand Down
94 changes: 90 additions & 4 deletions config/cypress.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,26 @@ version_config:
codeSystem: "2.16.840.1.113883.6.88"
CMSQRDA3SchematronValidator_warnings:
CMSQRDA1HQRSchematronValidator_warnings:
'~>2023.0':
start_date_offset: 2
modified_population_labels:
IPP: 'IPOP'
schematron: "2023.0.0"
qrda_version: "r5_3"
qrda_version_display_name: "STU 5.3"
qrda3_version: "r2_1"
qrda3_version_display_name: "R1"
mapped_codes:
default_negation_codes:
2.16.840.1.113883.3.526.3.1184:
code: "854901"
codeSystem: "2.16.840.1.113883.6.88"
2.16.840.1.113883.3.526.3.1174:
code: "854901"
codeSystem: "2.16.840.1.113883.6.88"
CMSQRDA3SchematronValidator_warnings:
- '2024 CMS QRDA III Implementation Guide for Eligible Clinicians is not available'
CMSQRDA1HQRSchematronValidator_warnings:

# Configuration for values to use when randomizing patients in test decks
# Names and nicknames added in a separate YML file
Expand Down Expand Up @@ -280,11 +300,25 @@ result_measures:
- hqmf_id : '2C928083-7F47-C81F-017F-6A10CDBE0958'
statement_name : 'SDE Results'
encounter_tuple_name : 'EncounterId'
# 2023 Bundle
# CMS529v4
- hqmf_id : '2C928084-83D3-1B44-0184-3A586CB316B5'
statement_name : 'SDE Results'
encounter_tuple_name : 'EncounterId'
# CMS844v4
- hqmf_id : '2C928084-83D3-1B44-0184-3A4838E816AC'
statement_name : 'SDE Results'
encounter_tuple_name : 'EncounterId'

# These eCQMs store a list of "Risk Variables" within the statement_results of an Individual Result
risk_variable_measures:
# CMS1028v1
- hqmf_id : '2C928082-7FAC-C041-017F-B75D24BE0605'
# 2023 Bundle
# CMS1028v2
- hqmf_id : '2C928084-82EA-D7C5-0183-3DCF0A3E17B3'
# CMS832v1
- hqmf_id : '2C928083-8651-08A3-0186-C7D18A711CB2'

# These eCQMs can have patients that are relevant to IPP even when they don't calculation into the IPP
ipp_relevant:
Expand All @@ -302,6 +336,27 @@ ipp_relevant:
# CMS190v11
- hqmf_id : '2C928083-7F47-C81F-017F-A3CEA9F0260D'
statements : [ 'Admission without VTE or Obstetrical Conditions']
# 2023 Bundle
# CMS136v13
- hqmf_id : '2C928084-8211-3ECE-0182-1DE98C500310'
statements : [ 'Inpatient Stay with Qualifying Diagnosis During Initiation Phase',
'Inpatient Stay with Qualifying Diagnosis During Continuation and Maintenance Phase']
# CMS137v12
- hqmf_id : '2C928084-82EA-D7C5-0182-EC98D1C20129'
statements : [ 'History of SUD Diagnosis or Treatment']
# CMS108v12
- hqmf_id : '2C928082-86DB-6718-0187-01000AFA078C'
statements : [ 'Admission without VTE or Obstetrical Conditions']
# CMS190v12
- hqmf_id : '2C928082-86DB-6718-0187-01042F1107A7'
statements : [ 'Admission without VTE or Obstetrical Conditions']
# CMS819v2
- hqmf_id : '2C928084-808A-9589-0180-8B94695C0128'
statements : [ 'Qualifying Encounter']
# CMS832v1
- hqmf_id : '2C928083-8651-08A3-0186-C7D18A711CB2'
statements : [ 'Inpatient Encounter with Creatinine']


# These measures do not
telehealth_ineligible_measures:
Expand Down Expand Up @@ -329,13 +384,16 @@ telehealth_ineligible_measures:

# These measures should not use information after measurement period
measures_without_future_data:
# CMS69v10, CMS69v11 (https://oncprojectracking.healthit.gov/support/browse/EKI-13)
# CMS69v10, CMS69v11, CMS69v12 (https://oncprojectracking.healthit.gov/support/browse/EKI-13)
[ '2C928083-786E-690D-0178-7090965F028D',
'2C928082-7FAC-C041-017F-B3038B3E0469' ]
'2C928082-7FAC-C041-017F-B3038B3E0469',
'2C928082-82CB-A3F5-0182-CC6968E30090' ]

# CMS996v3
# CMS996v3, CMS996v4, CMS1206v1
oqr_measures:
[ '2C928083-7F47-C81F-017F-79354C281550' ]
[ '2C928083-7F47-C81F-017F-79354C281550',
'2C928084-83D3-1B44-0184-77AC447D2178',
'2C928082-86DB-6718-0186-E05BA2AB0106' ]

# These measures have specific timing constraints
timing_constraints:
Expand All @@ -359,6 +417,15 @@ timing_constraints:
- hqmf_id : '2C928083-7F47-C81F-017F-6A10CDBE0958'
start_time : '20230701'
end_time : '20240630'
# 2023 Bundle
# CMS529v4
- hqmf_id : '2C928084-83D3-1B44-0184-3A586CB316B5'
start_time : '20240701'
end_time : '20250630'
# CMS844v4
- hqmf_id : '2C928084-83D3-1B44-0184-3A4838E816AC'
start_time : '20240701'
end_time : '20250630'

telehealth_modifier_codes:
[ '95', 'GQ', 'GT' ]
Expand Down Expand Up @@ -395,3 +462,22 @@ unit_matches:
code_list_id: '2.16.840.1.113762.1.4.1045.134'
units :
- 'mg/dL'
# 2023 Bundle
# relevant for CMS832v1+ Creatinine Mass Per Volume
- hqmf_set_id : '2C928083-8651-08A3-0186-C7D18A711CB2'
de_type : 'QDM::LaboratoryTestPerformed'
code_list_id: '2.16.840.1.113762.1.4.1248.21'
units :
- 'mg/dL'
# relevant for CMS871v3+ where BloodGlucoseLab.result >= 200 'mg/dL'
- hqmf_set_id : '2C928082-7FAC-C041-0180-1F512619243F'
de_type : 'QDM::LaboratoryTestPerformed'
code_list_id: '2.16.840.1.113762.1.4.1248.34'
units :
- 'mg/dL'
# relevant for CMS816v3+ where BloodGlucoseLab.result >= 200 'mg/dL'
- hqmf_set_id : '2C928084-82EA-D7C5-0183-3DA9C0411763'
de_type : 'QDM::LaboratoryTestPerformed'
code_list_id: '2.16.840.1.113762.1.4.1248.34'
units :
- 'mg/dL'
2 changes: 1 addition & 1 deletion config/initializers/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module Cypress
class Application
VERSION = '7.0.6'.freeze
VERSION = '7.1.0'.freeze
end
end
5 changes: 3 additions & 2 deletions contrib/cypress.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"aws_secret_key": "",
"default_user": "ubuntu",
"default_pwd": "CypressPwd",
"cypress_version": "cypress_7.0.6",
"cypress_version": "cypress_7.1.0",
"cvu_version": "cypress-validation-utility_3.2.2-production-1510258734",
"chef_version": "13.8.5",
"vpc_id": "",
Expand All @@ -17,12 +17,13 @@
"access_key": "{{user `aws_access_key`}}",
"secret_key": "{{user `aws_secret_key`}}",
"region": "us-east-1",
"source_ami": "ami-0e081ed4ce61c1fb2",
"source_ami": "ami-003d3d03cfe1b0468",
"instance_type": "t2.small",
"vpc_id": "{{user `vpc_id`}}",
"subnet_id": "{{user `subnet_id`}}",
"ami_virtualization_type": "hvm",
"ssh_username": "ubuntu",
"temporary_key_pair_type": "ed25519",
"ami_name": "cypress_{{ user `cypress_version` }}",
"ami_groups": "all",
"ami_block_device_mappings": [ {
Expand Down
17 changes: 12 additions & 5 deletions lib/ext/cqm/individual_result.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def compare_observations(calculated, issues = [])
expected_er = episode_results.values.map(&:observation_values).sort

return unless calculated_er != expected_er
# CQL requires a minimum of 8 decimal values. Cap our check there.
return unless calculated_er.round(8) != expected_er.round(8)

issues << "Calculated observations (#{calculated_er}) do not match " \
"expected observations (#{expected_er})"
Expand Down Expand Up @@ -177,11 +179,16 @@ def risk_variable_from_array(risk_variable_values, raw_results)
next unless rv_value

encounter_id = rv_value['id'] if (rv_value.is_a? Hash) && rv_value['qdmTitle'] == 'Encounter, Performed'
risk_variable_values[encounter_id] = if rv_value.is_a? Hash
rv_value['qdmTitle']
else
rv_value
end
# TODO: better support for CMS832
if encounter_id.nil?
risk_variable_values['Other'] = raw_results
else
risk_variable_values[encounter_id] = if rv_value.is_a? Hash
rv_value['qdmTitle']
else
rv_value
end
end
end
end

Expand Down
7 changes: 6 additions & 1 deletion lib/ext/cqm/patient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ def denormalize_date_times

# when laboratory_tests and physical_exams are reported for CMS529, they need to reference the
# encounter they are related to. The time range can include 24 hours before and after the encounter occurs.
# rubocop:disable Metrics/PerceivedComplexity
# rubocop:disable Metrics/CyclomaticComplexity
def add_encounter_ids_to_events
encounter_times = {}
qdmPatient.get_data_elements('encounter', 'performed').each do |ep|
Expand All @@ -204,7 +206,8 @@ def add_encounter_ids_to_events
encounter_times[ep.id] = rel_time
end
qdmPatient.get_data_elements('laboratory_test', 'performed').each do |lt|
lt.encounter_id = encounter_id_for_event(encounter_times, lt.resultDatetime)
event_time = lt.resultDatetime || lt.relevantDatetime || lt.relevantPeriod&.low
lt.encounter_id = encounter_id_for_event(encounter_times, event_time)
lt.relatedTo << lt.encounter_id if lt.encounter_id
end
qdmPatient.get_data_elements('physical_exam', 'performed').each do |pe|
Expand All @@ -213,6 +216,8 @@ def add_encounter_ids_to_events
pe.relatedTo << pe.encounter_id if pe.encounter_id
end
end
# rubocop:enable Metrics/CyclomaticComplexity
# rubocop:enable Metrics/PerceivedComplexity

def encounter_id_for_event(encounter_time_hash, event_time)
encounter_time_hash.each do |e_id, range|
Expand Down
14 changes: 8 additions & 6 deletions lib/tasks/bundle_eval.rake
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ namespace :bundle do
task :code_crosswalk, [:bundle_version] => :setup do |_, args|
bundle = Bundle.where(version: args.bundle_version).first
CSV.open('tmp/code_crosswalk.csv', 'w', col_sep: '|') do |csv|
bundle.measures.each do |measure|
bundle.measures.each_with_index do |measure, m_index|
puts m_index
valuesets = measure.value_sets
bundle.patients.each do |patient|
bundle.patients.each_with_index do |patient, p_index|
puts p_index
patient.qdmPatient.dataElements.each_with_index do |data_element, de_index|
cross_walks = false
codes = {}
Expand All @@ -23,7 +25,7 @@ namespace :bundle do
scooped_vs = valuesets.map { |vs| vs.oid if vs.concepts.any? { |vsc| do_codes_match?(dec, vsc) } }.compact
next if scooped_vs.blank?

code_hash = { code_system: dec['codeSystemOid'], valuesets: scooped_vs }
code_hash = { code_system: dec['system'], valuesets: scooped_vs }
codes[dec['code']] = code_hash
next unless codes.size.positive?

Expand All @@ -47,7 +49,7 @@ namespace :bundle do
# If a calculation difference already exists, no need to find more
next if calc_diffs

cw_patient.qdmPatient.dataElements[de_index].dataElementCodes = [{ 'code' => code, 'codeSystemOid' => value[:code_system] }]
cw_patient.qdmPatient.dataElements[de_index].dataElementCodes = [{ 'code' => code, 'system' => value[:code_system] }]
cw_patient.save
new_results = SingleMeasureCalculationJob.perform_now([cw_patient.id.to_s], measure.id.to_s, bundle.id.to_s, options)
# Set to true if difference is found
Expand Down Expand Up @@ -197,12 +199,12 @@ namespace :bundle do
end

def do_codes_match?(data_element_code, valueset_code)
valueset_code['code'] == data_element_code['code'] && valueset_code['code_system_oid'] == data_element_code['codeSystemOid']
valueset_code['code'] == data_element_code['code'] && valueset_code['code_system_oid'] == data_element_code['system']
end

def are_results_different?(original_results, new_results)
original_results.each do |original_result|
new_result = new_results.find(population_set_key: original_result.population_set_key).first
new_result = new_results.select { |nr| nr['population_set_key'] == original_result.population_set_key }.first
return true if result_different?(original_result, new_result)
end
false
Expand Down
2 changes: 2 additions & 0 deletions lib/validators/expected_results_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ def match_calculation_results(expected_result, reported_result, options, measure
def check_observations(expected_result, reported_result, measure_id)
expected_result[:observations].each do |population, expected_observation|
next if reported_result[:observations][population].to_d == expected_observation['value'].to_d
# CQL requires a minimum of 8 decimal values. Cap our check there.
next if reported_result[:observations][population].to_d.round(8) == expected_observation['value'].to_d.round(8)

err = %(Expected #{population} Observation value #{expected_observation['value']}
does not match reported value #{reported_result[:observations][population]})
Expand Down
4 changes: 2 additions & 2 deletions lib/validators/qrda_upload_validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def initialize(year, qrda_type, organization)
end

def qrda_1_validator(bundle_year, organization)
return unless [2020, 2021, 2022].include? bundle_year
return unless ApplicationController.helpers.supported_bundle_versions.include? bundle_year.to_s

if organization == 'hl7'
bundle_year > 2021 ? Cat1R53.instance : Cat1R52.instance
Expand All @@ -31,7 +31,7 @@ def qrda_1_validator(bundle_year, organization)
end

def qrda_3_validator(bundle_year, organization)
return unless [2020, 2021, 2022].include? bundle_year
return unless ApplicationController.helpers.supported_bundle_versions.include? bundle_year.to_s

if organization == 'hl7'
bundle_year > 2021 ? Cat3R1.instance : Cat3R21.instance
Expand Down
Loading