Class: HealthDataStandards::Import::CCR::PatientImporter
- Inherits:
-
Object
- Object
- HealthDataStandards::Import::CCR::PatientImporter
- Includes:
- Singleton
- Defined in:
- lib/health-data-standards/import/ccr/patient_importer.rb
Overview
This class is the central location for taking an ASTM CCR 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
Constant Summary collapse
- Gender =
{"male" => "M", "female" => "F"}
Instance Method Summary collapse
-
#add_measure(measure_id, importer) ⇒ Object
Adds a measure to run on a CCR that is passed in.
- #check_usable(check_usable_entries) ⇒ Object
-
#create_hash(doc, check_usable_entries = false) ⇒ Hash
Create a simple representation of the patient from an ASTM CCR.
-
#get_demographics(patient, doc, patient_id_xpath) ⇒ Object
Inspects a CCR document and populates the patient Hash with first name, last name birth date and gender.
-
#initialize(check_usable = true) ⇒ PatientImporter
constructor
Creates a new PatientImporter with the following XPath expressions used to find content in an ASTM CCR.
-
#parse_ccr(doc, patient_id_xpath = "//ccr:ContinuityOfCareRecord/ccr:Patient/ccr:ActorID") ⇒ Hash
Parses a ASTM CCR document and returns a Hash of of the patient.
-
#process_events(patient_record, entries) ⇒ Object
Adds the entries and denormalized measure information to the patient_record.
Constructor Details
#initialize(check_usable = true) ⇒ PatientImporter
Creates a new PatientImporter with the following XPath expressions used to find content in an ASTM CCR
Encounter entries
//ccr:Encounters/ccr:Encounter
Procedure entries
//ccr:Procedures/ccr:Procedure
Result entries -
//ccr:Results/ccr:Result
Vital sign entries
//ccr:VitalSigns/ccr:Result
Medication entries
//ccr:Medications/ccr:Medication
Codes for medications are found in the Product sections
./ccr:Product
Condition entries
//ccr:Problems/ccr:Problem
Social History entries
//ccr:SocialHistory/ccr:SocialHistoryElement
Care Goal entries
//ccr:Goals/ccr:Goal
Allergy entries
//ccr:Alerts/ccr:Alert
Immunization entries
//ccr:Immunizations/ccr:Immunization
Codes for immunizations are found in the substanceAdministration with the following relative XPath
./ccr:Product
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/health-data-standards/import/ccr/patient_importer.rb', line 55 def initialize (check_usable = true) @measure_importers = {} @section_importers = {} @section_importers[:encounters] = SimpleImporter.new("//ccr:Encounters/ccr:Encounter",:encounters) @section_importers[:procedures] = SimpleImporter.new("//ccr:Procedures/ccr:Procedure",:procedures) @section_importers[:results] = ResultImporter.new("//ccr:Results/ccr:Result",:results) @section_importers[:vital_signs] = ResultImporter.new("//ccr:VitalSigns/ccr:Result",:vital_signs) @section_importers[:medications] = ProductImporter.new("//ccr:Medications/ccr:Medication", :medications) @section_importers[:conditions] = SimpleImporter.new("//ccr:Problems/ccr:Problem",:conditions) @section_importers[:social_history] = SimpleImporter.new("//ccr:SocialHistory/ccr:SocialHistoryElement", :social_history) @section_importers[:care_goals] = SimpleImporter.new("//ccr:Goals/ccr:Goal",:care_goals) @section_importers[:medical_equipment] = ProductImporter.new("//ccr:Equipment/ccr:EquipmentElement",:medical_equipment) @section_importers[:allergies] = SimpleImporter.new("//ccr:Alerts/ccr:Alert",:allergies) @section_importers[:immunizations] = ProductImporter.new("//ccr:Immunizations/ccr:Immunization",:immunizations) end |
Instance Method Details
#add_measure(measure_id, importer) ⇒ Object
Adds a measure to run on a CCR that is passed in
163 164 165 |
# File 'lib/health-data-standards/import/ccr/patient_importer.rb', line 163 def add_measure(measure_id, importer) @measure_importers[measure_id] = importer end |
#check_usable(check_usable_entries) ⇒ Object
73 74 75 76 77 |
# File 'lib/health-data-standards/import/ccr/patient_importer.rb', line 73 def check_usable(check_usable_entries) @section_importers.each_pair do |section, importer| importer.check_for_usable = check_usable_entries end end |
#create_hash(doc, check_usable_entries = false) ⇒ Hash
Create a simple representation of the patient from an ASTM CCR
172 173 174 175 176 177 178 179 |
# File 'lib/health-data-standards/import/ccr/patient_importer.rb', line 172 def create_hash(doc, check_usable_entries = false) ccr_patient = {} @section_importers.each_pair do |section, importer| importer.check_for_usable = check_usable_entries ccr_patient[section] = importer.create_entries(doc) end ccr_patient end |
#get_demographics(patient, doc, patient_id_xpath) ⇒ Object
Inspects a CCR document and populates the patient Hash with first name, last name birth date and gender.
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 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/health-data-standards/import/ccr/patient_importer.rb', line 186 def get_demographics(patient, doc, patient_id_xpath) patientActorID = doc.at_xpath("//ccr:ContinuityOfCareRecord/ccr:Patient/ccr:ActorID").content patientActor = doc.at_xpath("//ccr:ContinuityOfCareRecord/ccr:Actors/ccr:Actor[ccr:ActorObjectID = \"#{patientActorID}\"]") patientID = patientActor.at_xpath(patient_id_xpath).try(:content) patientID ||= patientActorID name_element = patientActor.at_xpath('./ccr:Person/ccr:Name') if name_element if name_element.at_xpath("./ccr:CurrentName") patient['first'] = name_element.at_xpath('./ccr:CurrentName/ccr:Given').try(:content) patient['last'] = name_element.at_xpath('./ccr:CurrentName/ccr:Family').try(:content) elsif name_element.at_xpath("./ccr:DisplayName") # this will not work in all cases, but we're using it as a last resort if no CurrentName is found first, last = name_element.at_xpath("./ccr:DisplayName").content.split(" ") patient['first'] = first.strip patient['last'] = last.strip end end birthdate = patientActor.at_xpath('./ccr:Person//ccr:DateOfBirth/ccr:ExactDateTime | ./ccr:Person//ccr:DateOfBirth/ccr:ApproximateDateTime') patient['birthdate'] = Time.parse(birthdate.content).to_i if birthdate gender_string = patientActor.at_xpath('./ccr:Person/ccr:Gender/ccr:Text').content.downcase patient['gender'] = Gender[gender_string.downcase] #race_node = doc.at_xpath('/ccr:placeholder') #how do you find this? race = doc.at_xpath('//ccr:SocialHistory/ccr:SocialHistoryElement[./ccr:Type/ccr:Text = "Race"]/ccr:Description/ccr:Code[./ccr:CodingSystem = "CDC-RE"]/ccr:Value') ethnicity = doc.at_xpath('//ccr:SocialHistory/ccr:SocialHistoryElement[./ccr:Type/ccr:Text = "Ethnicity"]/ccr:Description/ccr:Code[./ccr:CodingSystem = "CDC-RE"]/ccr:Value') if ethnicity patient[:ethnicity] = {"code" => ethnicity.text, "codeSystem" => 'CDC-RE'} end if race patient[:race] = {"code" => race.text, "codeSystem" => 'CDC-RE'} end #ethnicity_node = doc.at_xpath() # languages = doc.at_xpath() patient['languages'] = nil patient['medical_record_number'] = patientID end |
#parse_ccr(doc, patient_id_xpath = "//ccr:ContinuityOfCareRecord/ccr:Patient/ccr:ActorID") ⇒ Hash
Parses a ASTM CCR document and returns a Hash of of the patient.
84 85 86 87 88 89 90 |
# File 'lib/health-data-standards/import/ccr/patient_importer.rb', line 84 def parse_ccr(doc, patient_id_xpath="//ccr:ContinuityOfCareRecord/ccr:Patient/ccr:ActorID") ccr_patient = {} entries = create_hash(doc) get_demographics(ccr_patient, doc, patient_id_xpath) process_events(ccr_patient, entries) Record.new(ccr_patient) end |
#process_events(patient_record, entries) ⇒ Object
Adds the entries and denormalized measure information to the patient_record. Each Entry will be converted to a Hash and stored in an Array under the appropriate section key, such as medications. Measure information is listed under the measures key which has a Hash value. The Hash has the measure id as a key, and the denormalized measure information as a value
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'lib/health-data-standards/import/ccr/patient_importer.rb', line 123 def process_events(patient_record, entries) patient_record['measures'] = {} @measure_importers.each_pair do |measure_id, importer| patient_record['measures'][measure_id] = importer.parse(entries) end entries.each_pair do |key, value| patient_record[key] = value.map do |e| if e.usable? e.to_hash else nil end end.compact end patient_record end |