Permalink
Browse files

Merge branch 'develop'

  • Loading branch information...
2 parents 3d61251 + 1f3d6ed commit f874873d5071c6c63fad867b156ed6302aa066e9 @andrequina andrequina committed Jan 25, 2012
Showing with 293 additions and 878 deletions.
  1. +2 −2 Gemfile
  2. +0 −8 Rakefile
  3. +1 −1 VERSION
  4. +13 −0 fixtures/mapping/test1_numerator.json
  5. +1 −1 fixtures/measures/sample_single/patients/manual_exclusion.json
  6. +1 −1 fixtures/patient_templates/healthy_older.json.erb
  7. +1 −1 fixtures/patient_templates/hypertensive_50_80.json.erb
  8. +1 −1 js/map_reduce_utils.js
  9. +4 −0 lib/qme/database_access.rb
  10. +49 −0 lib/qme/ext/record.rb
  11. +0 −5 lib/qme/ext/string.rb
  12. +0 −41 lib/qme/importer/code_system_helper.rb
  13. +0 −119 lib/qme/importer/entry.rb
  14. +24 −47 lib/qme/importer/generic_importer.rb
  15. +0 −27 lib/qme/importer/hl7_helper.rb
  16. +39 −0 lib/qme/importer/measure_properties_generator.rb
  17. +0 −228 lib/qme/importer/patient_importer.rb
  18. +0 −138 lib/qme/importer/section_importer.rb
  19. +1 −1 lib/qme/map/map_reduce_builder.rb
  20. +29 −25 lib/qme/map/map_reduce_executor.rb
  21. +5 −6 lib/qme/randomizer/patient_randomization_job.rb
  22. +47 −0 lib/qme/randomizer/random_patient_creator.rb
  23. +5 −8 lib/quality-measure-engine.rb
  24. +3 −3 lib/tasks/patient_random.rake
  25. +1 −1 quality-measure-engine.gemspec
  26. +0 −16 spec/qme/ext/string_spec.rb
  27. +0 −14 spec/qme/importer/code_system_helper_spec.rb
  28. +0 −66 spec/qme/importer/entry_spec.rb
  29. +11 −9 spec/qme/importer/generic_importer_spec.rb
  30. +0 −22 spec/qme/importer/hl7_helper_spec.rb
  31. +15 −0 spec/qme/importer/measure_properties_generator_spec.rb
  32. +0 −35 spec/qme/importer/patient_importer_spec.rb
  33. +5 −5 spec/qme/importer/property_matcher_spec.rb
  34. +0 −46 spec/qme/importer/section_importer_spec.rb
  35. +11 −0 spec/qme/map/patient_mapper_spec.rb
  36. +24 −1 spec/spec_helper.rb
View
@@ -5,11 +5,11 @@ gemspec :development_group => :test
gem 'mongo', '1.5.1'
gem 'bson_ext', '1.5.1', :platforms => :mri
gem 'rake'
-gem 'pry', :require => true
+#gem 'pry', :require => true
+gem 'health-data-standards', :git => 'https://github.com/projectcypress/health-data-standards.git', :branch => 'develop'
group :test do
gem 'cover_me', '>= 1.0.0.rc5', :platforms => :ruby_19
- gem 'metric_fu'
gem 'sinatra'
end
View
@@ -1,6 +1,5 @@
require 'rspec/core/rake_task'
require 'yard'
-require 'metric_fu'
require 'resque/tasks'
ENV['MEASURE_DIR'] = ENV['MEASURE_DIR'] || File.join('fixtures', 'measure_defs')
@@ -29,11 +28,4 @@ end
task :coverage do
Rake::Task['spec'].invoke
Rake::Task['cover_me:report'].invoke
-end
-
-MetricFu::Configuration.run do |config|
- #define which metrics you want to use
- config.metrics = [:roodi, :reek, :churn, :flog, :flay]
- config.graphs = [:flog, :flay]
- config.flay ={:dirs_to_flay => []} #Flay doesn't seem to be handling CLI arguments well... so this config squashes them
end
View
@@ -1 +1 @@
-1.0.4
+1.1.0
@@ -0,0 +1,13 @@
+{
+ "medical_record_number": "patient1",
+ "first": "Clark", // personal data
+ "last": "Kent",
+ "gender": "M",
+ "birthdate": 182908800, // Time.gm(1975, 10, 19).to_i
+ "test_id": null,
+ "measures": { // bag of measures, one entry per measure
+ "test1": {
+ "eyes": "green"
+ }
+ }
+}
@@ -2,7 +2,7 @@
"first": "Frederick", // personal data
"last": "Smith",
"gender": "M",
- "patient_id": "1234567890",
+ "medical_record_number": "1234567890",
"test_id": 1,
"birthdate": 182908800, // Time.gm(1975, 10, 19).to_i
"measures": { // bag of measures, one entry per measure
@@ -5,7 +5,7 @@
"last": "<%= surname %>",
"gender": "<%= sex %>",
"addresses": [<%= address %>],
- "patient_id": "<%= (0...10).map{ ('0'..'9').to_a[rand(10)] }.join.to_s %>",
+ "medical_record_number": "<%= (0...10).map{ ('0'..'9').to_a[rand(10)] }.join.to_s %>",
"birthdate": <%= between(Time.gm(1930, 1, 1), Time.gm(1960, 12, 31)) %>,
"events": {
"encounters": [
@@ -5,7 +5,7 @@
"last": "<%= surname %>",
"gender": "<%= sex %>",
"addresses": [<%= address %>],
- "patient_id": "<%= (0...10).map{ ('0'..'9').to_a[rand(10)] }.join.to_s %>",
+ "medical_record_number": "<%= (0...10).map{ ('0'..'9').to_a[rand(10)] }.join.to_s %>",
"birthdate": <%= between(Time.gm(1930, 1, 1), Time.gm(1960, 12, 31)) %>,
"events": {
"encounters": [
View
@@ -120,7 +120,7 @@ function() {
root.map = function(record, population, denominator, numerator, exclusion) {
var value = {population: false, denominator: false, numerator: false,
exclusions: false, antinumerator: false, patient_id: record._id,
- medical_record_id: record.patient_id,
+ medical_record_id: record.medical_record_number,
first: record.first, last: record.last, gender: record.gender,
birthdate: record.birthdate, test_id: record.test_id,
provider_performances: record.provider_performances,
@@ -24,6 +24,10 @@ def get_db
if @db == nil
@db = Mongo::Connection.new(@db_host, @db_port).db(@db_name)
end
+ Mongoid.configure do |config|
+ config.master = Mongo::Connection.new(@db_host, @db_port).db(@db_name)
+ end
+
@db
end
end
View
@@ -0,0 +1,49 @@
+# Extensions to the Record model in health-data-standards to support
+# quality measure calculation
+class Record
+ extend ActiveSupport::Memoizable
+
+ def procedure_results
+ results.to_a + vital_signs.to_a + procedures.to_a
+ end
+
+ def laboratory_tests
+ results.to_a + vital_signs.to_a
+ end
+
+ def all_meds
+ medications.to_a + immunizations.to_a
+ end
+
+ def active_diagnosis
+ conditions.any_of({:status => 'active'}, {:status => nil}).to_a +
+ social_history.any_of({:status => 'active'}, {:status => nil}).to_a
+ end
+
+ def inactive_diagnosis
+ conditions.any_of({:status => 'inactive'}, {:status => nil}).to_a +
+ social_history.any_of({:status => 'inactive'}, {:status => nil}).to_a
+ end
+
+ def resolved_diagnosis
+ conditions.any_of({:status => 'resolved'}, {:status => nil}).to_a +
+ social_history.any_of({:status => 'resolved'}, {:status => nil}).to_a
+ end
+
+ def all_problems
+ conditions.to_a + social_history.to_a
+ end
+
+ def all_devices
+ conditions.to_a + procedures.to_a + care_goals.to_a + medical_equipment.to_a
+ end
+
+ memoize :procedure_results
+ memoize :laboratory_tests
+ memoize :all_meds
+ memoize :active_diagnosis
+ memoize :inactive_diagnosis
+ memoize :resolved_diagnosis
+ memoize :all_problems
+ memoize :all_devices
+end
View
@@ -1,5 +0,0 @@
-class String
- def to_boolean
- ['1', 'true', 't'].include?(self.downcase)
- end
-end
@@ -1,41 +0,0 @@
-module QME
- module Importer
- # General helpers for working with codes and code systems
- class CodeSystemHelper
- CODE_SYSTEMS = {
- '2.16.840.1.113883.6.1' => 'LOINC',
- '2.16.840.1.113883.6.96' => 'SNOMED-CT',
- '2.16.840.1.113883.6.12' => 'CPT',
- #'2.16.840.1.113883.3.88.12.80.32' => 'CPT',
- '2.16.840.1.113883.6.88' => 'RxNorm',
- '2.16.840.1.113883.6.103' => 'ICD-9-CM',
- '2.16.840.1.113883.6.104' => 'ICD-9-CM',
- '2.16.840.1.113883.6.90' => 'ICD-10-CM',
- '2.16.840.1.113883.6.14' => 'HCPCS',
- '2.16.840.1.113883.6.59' => 'CVX',
- '2.16.840.1.113883.6.238' => 'CDC-RE'
- }
-
- # Returns the name of a code system given an oid
- # @param [String] oid of a code system
- # @return [String] the name of the code system as described in the measure definition JSON
- def self.code_system_for(oid)
- CODE_SYSTEMS[oid] || "Unknown"
- end
-
- # Returns the oid for a code system given a codesystem name
- # @param [String] the name of the code system
- # @return [String] the oid of the code system
- def self.oid_for_code_system(code_system)
- CODE_SYSTEMS.invert[code_system]
- end
-
- # Returns the whole map of OIDs to code systems
- # @terurn [Hash] oids as keys, code system names as values
- def self.code_systems
- CODE_SYSTEMS
- end
- end
- end
-end
-
View
@@ -1,119 +0,0 @@
-module QME
- module Importer
- # Object that represents a CDA Entry (or act, observation, etc.)
- class Entry
- attr_accessor :start_time, :end_time, :time, :status, :description
- attr_reader :codes, :value
-
- def initialize
- @codes = {}
- @value = {}
- end
-
- def self.from_event_hash(event)
- entry = Entry.new
- if event['code']
- entry.add_code(event['code'], event['code_set'])
- elsif event['codes']
- entry.instance_eval { @codes = event['codes'] }
- end
-
- entry.time = event['time']
- if event['value']
- entry.set_value(event['value'], event['unit'])
- end
- if event['description']
- entry.description = event['description']
- end
- if event['status']
- entry.status = event['status']
- end
- entry
- end
-
- # Add a code into the Entry
- # @param [String] code the code to add
- # @param [String] code_system the code system that the code belongs to
- def add_code(code, code_system)
- @codes[code_system] ||= []
- @codes[code_system] << code
- end
-
- # Sets the value for the entry
- # @param [String] scalar the value
- # @param [String] units the units of the scalar value
- def set_value(scalar, units=nil)
- @value[:scalar] = scalar
- @value[:units] = units
- end
-
- # Checks if a code is in the list of possible codes
- # @param [Array] code_set an Array of Hashes that describe the values for code sets
- # @return [true, false] whether the code is in the list of desired codes
- def is_in_code_set?(code_set)
- @codes.keys.each do |code_system|
- all_codes_in_system = code_set.find_all {|set| set['set'] == code_system}
- all_codes_in_system.each do |codes_in_system|
- matching_codes = codes_in_system['values'] & @codes[code_system]
- if matching_codes.length > 0
- return true
- end
- end
- end
- false
- end
-
- # Tries to find a single point in time for this entry. Will first return time if it is present,
- # then fall back to start_time and finally end_time
- def as_point_in_time
- if @time
- @time
- elsif @start_time
- @start_time
- else
- @end_time
- end
- end
-
- # Checks to see if this Entry can be used as a date range
- # @return [true, false] If the Entry has a start and end time returns true, false otherwise.
- def is_date_range?
- (! @start_time.nil?) && (! @end_time.nil?)
- end
-
- # Checks to see if this Entry is usable for measure calculation. This means that it contains
- # at least one code and has one of its time properties set (start, end or time)
- # @return [true, false]
- def usable?
- (! @codes.empty?) && ((! @start_time.nil?) || (! @end_time.nil?) || (! @time.nil?))
- end
-
- # Creates a Hash for this Entry
- # @return [Hash] a Hash representing the Entry
- def to_hash
- entry_hash = {}
- entry_hash['codes'] = @codes
- unless @value.empty?
- entry_hash['value'] = @value
- end
-
- if is_date_range?
- entry_hash['start_time'] = @start_time
- entry_hash['end_time'] = @end_time
- else
- entry_hash['time'] = as_point_in_time
- end
-
- if @status
- entry_hash['status'] = @status
- end
-
- if @description
- entry_hash['description'] = @description
- end
-
- entry_hash
- end
- end
- end
-end
Oops, something went wrong.

0 comments on commit f874873

Please sign in to comment.