Class: HealthDataStandards::Import::C32::PatientImporter
- Inherits:
-
Object
- Object
- HealthDataStandards::Import::C32::PatientImporter
- Includes:
- Util, Singleton
- Defined in:
- lib/health-data-standards/import/c32/patient_importer.rb
Overview
This class is the central location for taking a HITSP C32 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
Direct Known Subclasses
Instance Method Summary collapse
- #build_id_map(doc) ⇒ Object
-
#check_for_cause_of_death(c32_patient) ⇒ Object
Checks the conditions to see if any of them have a cause of death set.
- #check_usable(check_usable_entries) ⇒ Object
-
#create_c32_hash(record, doc) ⇒ Hash
Create a simple representation of the patient from a HITSP C32.
-
#get_demographics(patient, doc) ⇒ Object
Inspects a C32 document and populates the patient Hash with first name, last name birth date, gender and the effectiveTime.
-
#initialize(check_usable = true) ⇒ PatientImporter
constructor
Creates a new PatientImporter with the following XPath expressions used to find content in a HITSP C32:.
-
#parse_c32(doc) ⇒ Record
Parses a HITSP C32 document and returns a Hash of of the patient.
Constructor Details
#initialize(check_usable = true) ⇒ PatientImporter
Creates a new PatientImporter with the following XPath expressions used to find content in a HITSP C32:
Encounter entries
//cda:section[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.127']/cda:entry/cda:encounter
Procedure entries
//cda:procedure[cda:templateId/@root='2.16.840.1.113883.10.20.1.29']
Result entries - There seems to be some confusion around the correct templateId, so the code checks for both
//cda:observation[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.15.1'] | //cda:observation[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.15']
Vital sign entries
//cda:observation[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.14']
Medication entries
//cda:section[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.112']/cda:entry/cda:substanceAdministration
Codes for medications are found in the substanceAdministration with the following relative XPath
./cda:consumable/cda:manufacturedProduct/cda:manufacturedMaterial/cda:code
Condition entries
//cda:section[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.103']/cda:entry/cda:act/cda:entryRelationship/cda:observation
Codes for conditions are determined by examining the value child element as opposed to the code child element
Social History entries (non-C32 section, specified in the HL7 CCD)
//cda:observation[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.19']
Care Goal entries(non-C32 section, specified in the HL7 CCD)
//cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.1.25']
Allergy entries
//cda:observation[cda:templateId/@root='2.16.840.1.113883.10.20.1.18']
Immunization entries
//cda:substanceAdministration[cda:templateId/@root='2.16.840.1.113883.10.20.1.24']
Codes for immunizations are found in the substanceAdministration with the following relative XPath
./cda:consumable/cda:manufacturedProduct/cda:manufacturedMaterial/cda:code
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/health-data-standards/import/c32/patient_importer.rb', line 55 def initialize(check_usable = true) @section_importers = {} @section_importers[:encounters] = EncounterImporter.new @section_importers[:procedures] = ProcedureImporter.new @section_importers[:results] = ResultImporter.new @section_importers[:vital_signs] = VitalSignImporter.new @section_importers[:medications] = MedicationImporter.new @section_importers[:conditions] = ConditionImporter.new @section_importers[:social_history] = SectionImporter.new("//cda:observation[cda:templateId/@root='2.16.840.1.113883.3.88.11.83.19']") @section_importers[:care_goals] = CareGoalImporter.new @section_importers[:medical_equipment] = MedicalEquipmentImporter.new @section_importers[:allergies] = AllergyImporter.new @section_importers[:immunizations] = ImmunizationImporter.new @section_importers[:insurance_providers] = InsuranceProviderImporter.new end |
Instance Method Details
#build_id_map(doc) ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/health-data-standards/import/c32/patient_importer.rb', line 71 def build_id_map(doc) id_map = {} path = "//*[@ID]" ids = doc.xpath(path) ids.each do |id| tag = id['ID'] value = id.content id_map[tag] = value end id_map end |
#check_for_cause_of_death(c32_patient) ⇒ Object
Checks the conditions to see if any of them have a cause of death set. If they do, it will set the expired field on the Record. This is done here rather than replacing the expried method on Record because other formats may actully tell you whether a patient is dead or not.
111 112 113 114 115 |
# File 'lib/health-data-standards/import/c32/patient_importer.rb', line 111 def check_for_cause_of_death(c32_patient) if c32_patient.conditions.any? {|condition| condition.cause_of_death } c32_patient.expired = true end end |
#check_usable(check_usable_entries) ⇒ Object
85 86 87 88 89 |
# File 'lib/health-data-standards/import/c32/patient_importer.rb', line 85 def check_usable(check_usable_entries) @section_importers.each_pair do |section, importer| importer.check_for_usable = check_usable_entries end end |
#create_c32_hash(record, doc) ⇒ Hash
Create a simple representation of the patient from a HITSP C32
122 123 124 125 126 127 |
# File 'lib/health-data-standards/import/c32/patient_importer.rb', line 122 def create_c32_hash(record, doc) id_map = build_id_map(doc) @section_importers.each_pair do |section, importer| record.send(section.to_setter, importer.create_entries(doc, id_map)) end end |
#get_demographics(patient, doc) ⇒ Object
Inspects a C32 document and populates the patient Hash with first name, last name birth date, gender and the effectiveTime.
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/health-data-standards/import/c32/patient_importer.rb', line 134 def get_demographics(patient, doc) effective_date = doc.at_xpath('/cda:ClinicalDocument/cda:effectiveTime')['value'] patient.effective_time = HL7Helper.(effective_date) patient_element = doc.at_xpath('/cda:ClinicalDocument/cda:recordTarget/cda:patientRole/cda:patient') patient.first = patient_element.at_xpath('cda:name/cda:given').text patient.last = patient_element.at_xpath('cda:name/cda:family').text birthdate_in_hl7ts_node = patient_element.at_xpath('cda:birthTime') birthdate_in_hl7ts = birthdate_in_hl7ts_node['value'] patient.birthdate = HL7Helper.(birthdate_in_hl7ts) gender_node = patient_element.at_xpath('cda:administrativeGenderCode') patient.gender = gender_node['code'] id_node = doc.at_xpath('/cda:ClinicalDocument/cda:recordTarget/cda:patientRole/cda:id') patient.medical_record_number = id_node['extension'] # parse race, ethnicity, and spoken language race_node = patient_element.at_xpath('cda:raceCode') patient.race = { code: race_node['code'], code_set: 'CDC-RE' } if race_node ethnicity_node = patient_element.at_xpath('cda:ethnicGroupCode') patient.ethnicity = {code: ethnicity_node['code'], code_set: 'CDC-RE'} if ethnicity_node languages = patient_element.search('languageCommunication').map {|lc| lc.at_xpath('cda:languageCode')['code'] } patient.languages = languages unless languages.empty? end |
#parse_c32(doc) ⇒ Record
Parses a HITSP C32 document and returns a Hash of of the patient.
96 97 98 99 100 101 102 103 |
# File 'lib/health-data-standards/import/c32/patient_importer.rb', line 96 def parse_c32(doc) c32_patient = Record.new get_demographics(c32_patient, doc) create_c32_hash(c32_patient, doc) check_for_cause_of_death(c32_patient) c32_patient end |