class CQM::Converter::Utils
Public Class Methods
date_time_adjuster(results)
click to toggle source
Adjust improper date times from the cql_qdm_patientapi.
# File lib/cqm/converter/utils.rb, line 142 def self.date_time_adjuster(results) if results.is_a?(Hash) && results.key?('year') && results.key?('minute') seconds = results['second'] + (results['millisecond'] / 1000.0) DateTime.new(results['year'], results['month'], results['day'], results['hour'], results['minute'], seconds, results['timezoneOffset'].to_s).strftime('%Y-%m-%d %H:%M:%S.%N%Z') elsif results.is_a?(Hash) results.each do |key, value| results[key] = date_time_adjuster(value) end elsif results.is_a?(Array) results.map! { |result| date_time_adjuster(result) } else results end end
fix_infinity_dates(results)
click to toggle source
Remove any 'infinity' dates. The cql_qdm_patientapi adds an end time of 'infinity' if an event does not have an end time. Remove this when converting back to HDS from QDM.
# File lib/cqm/converter/utils.rb, line 160 def self.fix_infinity_dates(results) if results.is_a?(Hash) && results.key?('end_time') results.delete('end_time') if results['end_time'].to_s == '253402300799' elsif results.is_a?(Hash) results.each do |key, value| results[key] = fix_infinity_dates(value) end elsif results.is_a?(Array) results.map! { |result| fix_infinity_dates(result) } else results end end
gather_qdm_model_attrs()
click to toggle source
This helper method looks at the current state of cqm-models, and builds a hash of datatype models and their attributes.
# File lib/cqm/converter/utils.rb, line 31 def self.gather_qdm_model_attrs qdm_model_attrs = {} QDM.constants.each do |model| if QDM.const_get(model).respond_to?('fields') qdm_model_attrs[model.to_s] = QDM.const_get(model).fields.keys.map! { |a| a.camelize(:lower) } end if QDM.const_get(model).respond_to?('embedded_relations') qdm_model_attrs[model.to_s].concat(QDM.const_get(model).embedded_relations.keys.map! { |a| a.camelize(:lower) }) end end # TODO: This field is currently not supported. See: # https://github.com/projecttacoma/cql_qdm_patientapi/search?q=does+not+currently+support qdm_model_attrs['PatientCharacteristicExpired'].delete('cause') qdm_model_attrs end
gather_qdm_to_hds_mappings(qdm_model_attrs = nil)
click to toggle source
Parse the cql_qdm_patientapi datatypes to infer how to construct corresponding HDS entries.
# File lib/cqm/converter/utils.rb, line 49 def self.gather_qdm_to_hds_mappings(qdm_model_attrs = nil) qdm_model_attrs = gather_qdm_model_attrs if qdm_model_attrs.nil? cql_qdm_patientapi_spec = Gem::Specification.find_by_name('cql_qdm_patientapi') datatypes = Dir.glob(cql_qdm_patientapi_spec.gem_dir + '/app/assets/javascripts/datatypes/*.coffee') # Read in all datatypes datatypes_contents = '' datatypes.each do |datatype| datatypes_contents += File.read(datatype) + "\n" end datatypes_contents += 'class' # Construct the mappings qdm_to_hds_mappings = {} qdm_model_attrs.each do |datatype, attributes| datatype_pattern = /#{datatype} extends CQL_QDM.QDMDatatype.*?class/m next unless (dc_class = datatype_pattern.match(datatypes_contents)) qdm_to_hds_mappings[datatype] = {} attributes.each do |attribute| attribute_pattern = /@_#{attribute}(Low|High| ).*?$/ dc_class.to_s.to_enum(:scan, attribute_pattern).map do dc_attr = Regexp.last_match # TODO: adjust regexes used here to parse out the timing information # Handle possible mixed values. if dc_attr.to_s.include? 'Low' qdm_to_hds_mappings[datatype][attribute] = {} unless qdm_to_hds_mappings[datatype][attribute] qdm_to_hds_mappings[datatype][attribute][:low] = dc_attr.to_s[/(.*?)(\)|$|\?)/m, 1] elsif dc_attr.to_s.include? 'High' qdm_to_hds_mappings[datatype][attribute] = {} unless qdm_to_hds_mappings[datatype][attribute] qdm_to_hds_mappings[datatype][attribute][:high] = dc_attr.to_s[/(.*?)(\)|$|\?)/m, 1] else qdm_to_hds_mappings[datatype][attribute] = dc_attr.to_s[/(.*?)(\)|$|\?)/m, 1] end end end end qdm_to_hds_mappings end
hds_codes_to_qdm_codes(hds_codes)
click to toggle source
Convert HDS codes structure to QDM codes structure.
# File lib/cqm/converter/utils.rb, line 19 def self.hds_codes_to_qdm_codes(hds_codes) qdm_codes = [] hds_codes.each do |code_system, codes| codes.each do |code| qdm_codes << { codeSystem: code_system, code: code } end end qdm_codes end
hds_to_qdm_js(js_dependencies, record, qdm_model_attrs)
click to toggle source
Builds JavaScript to assist the HDS Record to QDM Patient conversion.
# File lib/cqm/converter/utils.rb, line 88 def self.hds_to_qdm_js(js_dependencies, record, qdm_model_attrs) record_json = JSON.parse(record.to_json) # Bonnie changes start_date and end_date in the front end before calculation, # and this is what is expected by the cql_qdm_patientapi, so make that change # before generating the executable JavaScript. record_json = record_json.deep_transform_keys { |key| key.to_s == 'start_date' ? 'start_time' : key } record_json = record_json.deep_transform_keys { |key| key.to_s == 'end_date' ? 'end_time' : key } <<-JS window = {}; #{js_dependencies}; function PatientWrapper() { } PatientWrapper.prototype.get = function(attr) { const contents = #{record_json.to_json}; return contents[attr]; } cql = window.cql; patient = new CQL_QDM.CQLPatient(new PatientWrapper()); raw_datatypes = patient.buildDatatypes(); qdm_model_attrs = #{qdm_model_attrs.to_json}; processed_datatypes = {}; // Loop over each QDM datatype. Object.keys(raw_datatypes).forEach(function(key) { processed_datatypes[key] = []; // Collect the values of the QDM attributes. raw_datatypes[key].forEach(function(datatype) { results = {}; qdm_model_attrs[datatype.constructor.name].forEach(function(method) { // Call the datatype attribute method to get its value. if (datatype[method]) { result = datatype[method](); // Handle CQL execution engine type results. if (result && result['toJSON']) { results[method] = result.toJSON(); } else { results[method] = result; } } }); // Add codes to result. results['dataElementCodes'] = datatype['getCode'](); // Add description to result. results['description'] = datatype['_description']; // Add oid to result. results['hqmfOid'] = datatype['_oid']; processed_datatypes[key].push(results); }); }); return processed_datatypes; JS end
qdm_codes_to_hds_codes(qdm_codes)
click to toggle source
Convert QDM codes structure to HDS codes structure.
# File lib/cqm/converter/utils.rb, line 6 def self.qdm_codes_to_hds_codes(qdm_codes) codes = {} qdm_codes.each do |qdm_code| qdm_code = qdm_code.stringify_keys code_system = qdm_code['codeSystem'] code_system = qdm_code['code_system'] if qdm_code['code_system'] codes[code_system] = [] unless codes.key? code_system codes[code_system] << qdm_code['code'] if qdm_code['code'] end codes end
qdm_to_hds_class_type(category)
click to toggle source
Helper method to handle mismatched HDS Class names for QDM things.
# File lib/cqm/converter/utils.rb, line 175 def self.qdm_to_hds_class_type(category) if category.to_s.include? 'diagnostic' 'procedure' elsif category.to_s.include? 'physical_exam' 'procedure' elsif category.to_s.include? 'intervention' 'procedure' elsif category.to_s.include? 'device' 'medical_equipment' elsif category.to_s.include? 'laboratory' 'vital_sign' elsif category.to_s.include? 'substance' 'medication' elsif category.to_s.include? 'immunization' 'medication' else category end end