Comments (2)
The following monkeypatch, under the assumption it should be 1.29 and not 1.129, makes measure 0089 passable in cypress.
module HealthDataStandards
module Import
module Cat1
# This class is the central location for taking a QRDA Cat 1 XML document and converting it
# into the processed form we store in MongoDB. The class does this by running each measure
# independently on the XML document
#
# This class is a Singleton. It should be accessed by calling PatientImporter.instance
class PatientImporter
alias_method :original_initialize, :initialize
def initialize
original_initialize
# MONKEY PATCH: USING 1.129 (negative) instead of 1.29 (positive) for P2P Communication
begin
index = @section_importers[:procedures].find_index { |p| p.hqmf_oid == '2.16.840.1.113883.3.560.1.129'}
if index.present?
ptpcomm = @section_importers[:procedures][index]
ptpcomm.hqmf_oid = '2.16.840.1.113883.3.560.1.29'
@section_importers[:procedures][index] = ptpcomm
puts "monkey patched initialize: #{@section_importers[:procedures][index].to_yaml}"
else
puts "MONKEY PATCH FAILED!"
end
rescue
puts "Error #{$!}"
end
end
end
end
end
end
from health-data-standards.
Actually the issue, I think, is much bigger than this. As I said above, it's not just the OID, but it's the NEGATIVE OID. Well that negative (NOT DONE) version needs to be accounted for to. And from what I see, it's not accounted for anywhere in the importer.
When generating QRDA III documents and doing performance calculations, everything still seems to come out fine. But when re-generating QRDA I documents, things don't go so well. So in order to combat this, I did 2 things:
- I implemented a negative version of each code. Usually that's adding 100 to the last numeric sequence in the OID. So if ti's 1.2.3.4 then the negative version of that OID is 1.2.3.104. If it's 1.2.3.95 then the negative version is 1.2.3.195. In the few cases that doesn't follow suit, the naming convention seems to be NOT DONE. So if the OID name is "Medication, Given" then the negative version is "Medication, Given not done." So given that, I implemented an automatic find-and-use negative version of codes passed in that hinges off of the
negationInd
flag. - There were a bunch of codes in the patient importer that were incorrectly pointed to the negative version of the code. So I removed those and re-add them from the positive.
Here's the full monkey patch. I'm more than happy to turn this into a pull request and update the core code. I just need to know that it will actually be merged. I don't want to waste my time. This project seems very inactive. So I'm at least putting this here for the sake of others.
NOTE: with this monkey patch, I get 100% success flags on all ambulatory and inpatient Cypress tests on the latest package.
module HealthDataStandards
module Import
module Cat1
class PatientImporter
alias_method :original_initialize, :initialize
def initialize
original_initialize
# MONKEY PATCH: USING 1.129 (negative) instead of 1.29 (positive) for Provider To Provider Communication
# MONKEY PATCH: USING 1.103 (negative) instead of 1.3 (positive) for Diagnostic Study, Performed
# MONKEY PATCH: USING 1.131 (negative) instead of 1.31 (positive) for Communication: From Provider to Patient
# MONKEY PATCH: USING 1.110 (negative) instead of 1.10 (positive) for Device, Applied
# MONKEY PATCH: Missing Substance, Administered
begin
index = @section_importers[:procedures].find_index { |p| p.hqmf_oid == '2.16.840.1.113883.3.560.1.129'}
if index.present?
importer = generate_importer(Cat1::ProcedureImporter, nil, '2.16.840.1.113883.3.560.1.29') #comm from provider to provider
@section_importers[:procedures][index] = importer
# puts "monkey patched initialize: #{@section_importers[:procedures][index].to_yaml}"
else
puts "MONKEY PATCH FAILED! - 129"
end
index = @section_importers[:procedures].find_index { |p| p.hqmf_oid == '2.16.840.1.113883.3.560.1.103'}
if index.present?
importer = generate_importer(CDA::ProcedureImporter, "./cda:entry/cda:observation[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.18']", '2.16.840.1.113883.3.560.1.3', 'performed') #diagnostic study performed
@section_importers[:procedures][index] = importer
# puts "monkey patched initialize: #{@section_importers[:procedures][index].to_yaml}"
else
puts "MONKEY PATCH FAILED! - 103"
end
index = @section_importers[:procedures].find_index { |p| p.hqmf_oid == '2.16.840.1.113883.3.560.1.131'}
if index.present?
importer = generate_importer(CDA::ProcedureImporter, "./cda:entry/cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.3']", '2.16.840.1.113883.3.560.1.31') #comm from provider to patient
@section_importers[:procedures][index] = importer
# puts "monkey patched initialize: #{@section_importers[:procedures][index].to_yaml}"
else
puts "MONKEY PATCH FAILED! - 131"
end
index = @section_importers[:medical_equipment].find_index { |p| p.hqmf_oid == '2.16.840.1.113883.3.560.1.110'}
if index.present?
importer = generate_importer(CDA::MedicalEquipmentImporter, "./cda:entry/cda:procedure[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.7']", '2.16.840.1.113883.3.560.1.10', 'applied')
@section_importers[:medical_equipment][index] = importer
# puts "monkey patched initialize: #{@section_importers[:procedures][index].to_yaml}"
else
puts "MONKEY PATCH FAILED! - 110"
end
index = @section_importers[:medications].find_index { |p| p.hqmf_oid == '2.16.840.1.113883.3.560.1.14'}
if index.present?
importer = generate_importer(CDA::MedicationImporter, "./cda:entry/cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.42']/cda:entryRelationship/cda:substanceAdministration[cda:templateId/@root='2.16.840.1.113883.10.20.22.4.16' and cda:text[not(contains(text(), 'Substance'))] ]", '2.16.840.1.113883.3.560.1.14', 'administered') #medication administered
@section_importers[:medications][index] = importer
importer = generate_importer(CDA::MedicationImporter, "./cda:entry/cda:act[cda:templateId/@root = '2.16.840.1.113883.10.20.24.3.42']/cda:entryRelationship/cda:substanceAdministration[cda:templateId/@root='2.16.840.1.113883.10.20.22.4.16' and cda:text[contains(text(), 'Substance')] ]", '2.16.840.1.113883.3.560.1.64', 'administered') # substance administered
@section_importers[:medications] << importer
# puts "monkey patched initialize: #{@section_importers[:procedures][index].to_yaml}"
else
puts "MONKEY PATCH FAILED! - 14"
end
rescue => e
puts "OOPS! #{e.inspect}"
puts e.backtrace
end
end
# def import_sections(record, doc)
#
# context = doc.xpath("/cda:ClinicalDocument/cda:component/cda:structuredBody/cda:component/cda:section[cda:templateId/@root = '2.16.840.1.113883.10.20.24.2.1']")
# nrh = CDA::NarrativeReferenceHandler.new
# nrh.build_id_map(doc)
# @section_importers.each do |section, entry_packages|
# entry_packages.each do |entry_package|
# puts "#{section.to_json} - #{entry_package.to_json} - #{entry_package.package_entries(context, nrh).to_json}" if section.to_s == 'procedures' && entry_package.package_entries(context, nrh).length > 0
# record.send(section) << entry_package.package_entries(context, nrh)
# end
# end
#end
end
end
end
end
module HealthDataStandards
module Import
module CDA
class SectionImporter
private
alias_method :original_extract_code, :extract_code
# MONKEY PATCH: Only return code_hash if a code was found (fix for codeClass="UNK")
# MONKEY PATCH: template generators expect code_system not codeSystem
def extract_code(parent_element, code_xpath, code_system=nil)
code_hash = original_extract_code parent_element, code_xpath, code_system
code_hash = nil unless code_hash.present? && code_hash['code'].present?
if code_hash.present?
code_hash['code_system'] = code_hash['codeSystem'] if code_hash['codeSystem']
code_hash['code_system_oid'] = code_hash['codeSystemOid'] if code_hash['codeSystemOid']
end
code_hash
end
end
end
end
end
module HealthDataStandards
module Import
module Cat1
class EntryPackage
attr_accessor :oid_hash, :status_hash
alias_method :original_initialize, :initialize
def initialize (type, oid, stat = nil)
begin
if oid.is_a?(Hash)
self.oid_hash = oid
oid = oid[:positive]
else
self.oid_hash = { positive: oid, negative: find_negative(oid) }
end
if stat.is_a?(Hash)
self.status_hash = stat
stat = stat[:positive]
else
self.status_hash = { positive: stat }
self.status_hash[:negative] = "not " + stat if stat.present?
end
return original_initialize(type, oid, stat)
rescue => e
puts "OOPS! #{e.inspect}"
puts e.backtrace
end
end
def find_negative(oid)
neg_oid = oid.dup # copy
ri = neg_oid.rindex('.')
rn = neg_oid[ri + 1, 10].to_i
if rn < 1000
rn = rn + 100
else
rn = '1' + rn.to_s
end
neg_oid = neg_oid[0, ri + 1] + rn.to_s
ret = oid # default ret if can't find
by_id = HealthDataStandards::Export::QRDA::EntryTemplateResolver.hqmf_qrda_oid_map.select { |e|
e['hqmf_oid'] == oid
}
if by_id.length == 1
# found just one positive... let's do it
negs = HealthDataStandards::Export::QRDA::EntryTemplateResolver.hqmf_qrda_oid_map.select { |e|
e['qrda_oid'] == by_id[0]['qrda_oid'] && (e['hqmf_oid'] == neg_oid || e['hqmf_name'] == by_id[0]['hqmf_name'] + " not done")
}
if negs.length == 1
ret = negs[0]['hqmf_oid']
puts " FOUND NEG FOR #{oid}: #{negs[0].to_json}"
puts " NEG SET, BUT ID MISMATCH FOR #{oid}: #{ret} != #{neg_oid}" if neg_oid != ret
else
puts " NO NEG FOR #{oid}: neg_by_name.length: #{negs.length}"
end
else
puts " NO NEG SET FOR #{oid}: by_id.length: #{by_id.length}"
end
#puts " NEG SET: #{ret} for #{oid}" if oid != ret
return ret
end
def select_oid(entry)
return self.oid_hash[:positive] unless entry.negation_ind
return self.oid_hash[:negative] if entry.negation_ind
end
def select_status(entry)
return self.status_hash[:positive] unless entry.negation_ind
return self.status_hash[:negative] if entry.negation_ind
end
def package_entries (doc, nrh)
entries = self.importer_type.create_entries(doc, nrh)
entries.each do |entry|
begin
entry.oid = self.select_oid(entry)
entry.status = self.select_status(entry)
rescue
"DOH! #{$!}"
end
end
entries
end
end
end
end
end
from health-data-standards.
Related Issues (20)
- Is hqmf1.xml retired? HOT 1
- Parser fix possibly not applied in rubygems 3.6.1 HOT 1
- Rails 4.2? HOT 2
- bundle-latest.zip no longer exists on the new demo server HOT 3
- question about field_value_helper.rb
- Provided TIN not imported from qrda/cda in provider_importer.rb HOT 4
- Question: What is the roadmap for merging the `mongoid5` branch? HOT 1
- Ruby 2.4 HOT 19
- Test failures for cat_1 test HOT 2
- Medication importer with Reason Underweight issue for measure CMS69 (CAT1) HOT 1
- Using without MongoDB HOT 2
- QRDA-1: Encounters not parsing HOT 1
- QRDA-1: CMS68v6 > Procedures > Not Done HOT 1
- CDA > MedicationImporter HOT 1
- Freeze all constants in provider.rb
- Any relation to 2015 CEHRT? HOT 2
- HealthDataStandards::Export::Cat1 HOT 1
- Basic use documentation HOT 1
- Citation(s) HOT 1
- health-data-standards on https://rubygems.org HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from health-data-standards.