diff --git a/Gemfile b/Gemfile index a77ade1a8..f5d2c0348 100644 --- a/Gemfile +++ b/Gemfile @@ -6,13 +6,13 @@ gem 'jquery-rails' gem 'jquery-ui-rails' gem 'rake' - # gem 'quality-measure-engine', :git => 'https://github.com/pophealth/quality-measure-engine.git', :branch => 'master' # gem 'quality-measure-engine', :path => '../quality-measure-engine' gem 'quality-measure-engine', '3.1.2' -gem 'health-data-standards', "3.5.3" +#gem 'health-data-standards', "3.5.3" +gem 'health-data-standards',:git => 'https://github.com/ESRogs/health-data-standards.git', :branch => 'master' # gem 'health-data-standards',:git => 'https://github.com/projectcypress/health-data-standards.git', :branch => 'master' diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 0ceaf880d..000000000 --- a/Gemfile.lock +++ /dev/null @@ -1,268 +0,0 @@ -GEM - remote: http://rubygems.org/ - specs: - Ascii85 (1.0.2) - aasm (3.3.1) - actionmailer (4.1.8) - actionpack (= 4.1.8) - actionview (= 4.1.8) - mail (~> 2.5, >= 2.5.4) - actionpack (4.1.8) - actionview (= 4.1.8) - activesupport (= 4.1.8) - rack (~> 1.5.2) - rack-test (~> 0.6.2) - actionview (4.1.8) - activesupport (= 4.1.8) - builder (~> 3.1) - erubis (~> 2.7.0) - activemodel (4.1.8) - activesupport (= 4.1.8) - builder (~> 3.1) - activerecord (4.1.8) - activemodel (= 4.1.8) - activesupport (= 4.1.8) - arel (~> 5.0.0) - activesupport (4.1.8) - i18n (~> 0.6, >= 0.6.9) - json (~> 1.7, >= 1.7.7) - minitest (~> 5.1) - thread_safe (~> 0.1) - tzinfo (~> 1.1) - addressable (2.3.6) - ansi (1.4.3) - arel (5.0.1.20140414130214) - bcrypt (3.1.7) - bson (2.3.0) - builder (3.2.2) - cache_digests (0.3.1) - actionpack (>= 3.2) - thread_safe - cancan (1.6.10) - cane (2.6.2) - parallel - carrierwave (0.10.0) - activemodel (>= 3.2.0) - activesupport (>= 3.2.0) - json (>= 1.7) - mime-types (>= 1.16) - carrierwave-mongoid (0.7.1) - carrierwave (>= 0.8.0, < 0.11.0) - mongoid (>= 3.0, < 5.0) - mongoid-grid_fs (>= 1.3, < 3.0) - coderay (1.1.0) - connection_pool (2.1.0) - crack (0.4.2) - safe_yaml (~> 1.0.0) - daemons (1.1.9) - delayed_job (4.0.2) - activesupport (>= 3.0, < 4.2) - delayed_job_mongoid (2.1.0) - delayed_job (>= 3.0, < 5) - mongoid (>= 3.0, < 5) - devise (3.2.4) - bcrypt (~> 3.0) - orm_adapter (~> 0.1) - railties (>= 3.2.6, < 5) - thread_safe (~> 0.1) - warden (~> 1.2.3) - docile (1.1.5) - erubis (2.7.0) - eventmachine (1.0.3) - execjs (2.2.1) - health-data-standards (3.5.3) - activesupport (~> 4.1.1) - builder (~> 3.1) - erubis (~> 2.7.0) - log4r (~> 1.1.10) - memoist (~> 0.9.1) - mongoid (~> 4.0.0) - mongoid-tree (~> 1.0.4) - nokogiri (= 1.6.0) - protected_attributes (~> 1.0.5) - rest-client (~> 1.6.7) - rubyzip (= 0.9.9) - uuid (~> 2.3.7) - highline (1.6.21) - hike (1.2.3) - i18n (0.7.0) - jquery-rails (3.1.1) - railties (>= 3.0, < 5.0) - thor (>= 0.14, < 2.0) - jquery-ui-rails (5.0.0) - railties (>= 3.2.16) - json (1.8.2) - libv8 (3.16.14.3) - log4r (1.1.10) - macaddr (1.7.1) - systemu (~> 2.6.2) - mail (2.6.3) - mime-types (>= 1.16, < 3) - memoist (0.9.3) - metaclass (0.0.4) - method_source (0.8.2) - mime-types (1.25.1) - mini_portile (0.5.3) - minitest (5.5.1) - mocha (1.1.0) - metaclass (~> 0.0.1) - mongoid (4.0.0) - activemodel (~> 4.0) - moped (~> 2.0.0) - origin (~> 2.1) - tzinfo (>= 0.3.37) - mongoid-grid_fs (2.1.0) - mime-types (>= 1.0, < 3.0) - mongoid (>= 3.0, < 5.0) - mongoid-tree (1.0.4) - mongoid (>= 3.0, <= 4.0) - mongoid_rails_migrations (1.0.1) - activesupport (>= 3.2.0) - bundler (>= 1.0.0) - rails (>= 3.2.0) - railties (>= 3.2.0) - moped (2.0.3) - bson (~> 2.2) - connection_pool (~> 2.0) - optionable (~> 0.2.0) - multi_json (1.10.1) - nokogiri (1.6.0) - mini_portile (~> 0.5.0) - optionable (0.2.0) - origin (2.1.1) - orm_adapter (0.5.0) - parallel (1.0.0) - pdf-core (0.2.5) - pdf-reader (0.9.0) - Ascii85 (>= 0.9) - prawn (1.1.0) - pdf-core (~> 0.2.5) - ttfunk (~> 1.2.0) - protected_attributes (1.0.8) - activemodel (>= 4.0.1, < 5.0) - pry (0.9.12.6) - coderay (~> 1.0) - method_source (~> 0.8) - slop (~> 3.4) - pry-nav (0.2.3) - pry (~> 0.9.10) - quality-measure-engine (3.1.2) - delayed_job_mongoid (~> 2.1.0) - mongoid (~> 4.0.0) - moped (~> 2.0.0) - rubyzip (~> 0.9.9) - rack (1.5.2) - rack-test (0.6.2) - rack (>= 1.0) - rails (4.1.8) - actionmailer (= 4.1.8) - actionpack (= 4.1.8) - actionview (= 4.1.8) - activemodel (= 4.1.8) - activerecord (= 4.1.8) - activesupport (= 4.1.8) - bundler (>= 1.3.0, < 2.0) - railties (= 4.1.8) - sprockets-rails (~> 2.0) - rails-perftest (0.0.4) - railties (4.1.8) - actionpack (= 4.1.8) - activesupport (= 4.1.8) - rake (>= 0.8.7) - thor (>= 0.18.1, < 2.0) - rake (10.3.2) - rdoc (4.2.0) - json (~> 1.4) - ref (1.0.5) - rest-client (1.6.8) - mime-types (~> 1.16) - rdoc (>= 2.4.2) - ruby-graphviz (1.2.1) - ruby-prof (0.15.1) - rubyzip (0.9.9) - safe_yaml (1.0.3) - sass (3.2.19) - simple_form (3.0.2) - actionpack (~> 4.0) - activemodel (~> 4.0) - simplecov (0.9.1) - docile (~> 1.1.0) - multi_json (~> 1.0) - simplecov-html (~> 0.8.0) - simplecov-html (0.8.0) - slop (3.5.0) - sprockets (2.12.3) - hike (~> 1.2) - multi_json (~> 1.0) - rack (~> 1.0) - tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.2.0) - actionpack (>= 3.0) - activesupport (>= 3.0) - sprockets (>= 2.8, < 4.0) - systemu (2.6.4) - therubyracer (0.12.1) - libv8 (~> 3.16.14.0) - ref - thin (1.6.2) - daemons (>= 1.0.9) - eventmachine (>= 1.0.0) - rack (>= 1.0.0) - thor (0.19.1) - thread_safe (0.3.4) - tilt (1.4.1) - ttfunk (1.2.0) - turn (0.9.6) - ansi - tzinfo (1.2.2) - thread_safe (~> 0.1) - uglifier (2.5.1) - execjs (>= 0.3.0) - json (>= 1.8.0) - uuid (2.3.7) - macaddr (~> 1.0) - warden (1.2.3) - rack (>= 1.0) - webmock (1.18.0) - addressable (>= 2.3.6) - crack (>= 0.3.2) - -PLATFORMS - ruby - -DEPENDENCIES - aasm - bson - cache_digests - cancan (~> 1.6.7) - cane - carrierwave - carrierwave-mongoid - delayed_job_mongoid - devise (~> 3.2) - health-data-standards (= 3.5.3) - highline - jquery-rails - jquery-ui-rails - mocha - mongoid-grid_fs (~> 2.1.0) - mongoid_rails_migrations (~> 1.0) - pdf-reader (= 0.9.0) - prawn - pry - pry-nav - quality-measure-engine (= 3.1.2) - rails (~> 4.1.8) - rails-perftest - rake - ruby-graphviz - ruby-prof - sass - simple_form - simplecov - therubyracer - therubyrhino - thin - turn - uglifier - webmock diff --git a/app/models/calculated_product_test.rb b/app/models/calculated_product_test.rb index 9f56773c8..5ae90efe6 100644 --- a/app/models/calculated_product_test.rb +++ b/app/models/calculated_product_test.rb @@ -1,4 +1,4 @@ - +require 'zip/zip' class CalculatedProductTest < ProductTest aasm :column => :state do @@ -20,6 +20,46 @@ class CalculatedProductTest < ProductTest #after the test is created generate the population after_create :gen_pop + def initialize(args = nil) + if args != nil + if args.has_key?("test_zip") + test_zip = args["test_zip"] + @uploaded_patient_xml_strings = get_file_contents_from_zip(test_zip) + # ROGTODO: should the patient strings be passed as part of agrs to super? + measure_ids = get_measure_ids_from_patient_xml_string(@uploaded_patient_xml_strings[0]) + @uploaded_patient_xml_strings.each do |ps| + patient_measure_ids = get_measure_ids_from_patient_xml_string(ps) + patient_measure_ids.each { |pmi| raise "Patients have different measure ids!" unless measure_ids.include?(pmi) } + end + # ROGTODO: don't hardcode effective_date + return super({"name"=>args["name"], "product_id"=>args["product_id"], "effective_date"=>"1388534399", "measure_ids"=>measure_ids}) + end + end + super(args) + end + + def get_file_contents_from_zip(test_zip) + data = test_zip.open.read + content_strings = [] + Zip::ZipFile.open(test_zip.path()) do |zipfile| + zipfile.each do |entry| + cs = entry.get_input_stream.read + content_strings.push(cs) + end + end + content_strings + end + + def get_measure_ids_from_patient_xml_string(patient_xml_string) + doc = Nokogiri::XML(patient_xml_string) + # ROGTODO: handle other formats? + doc.root.add_namespace_definition('cda', 'urn:hl7-org:v3') + nodes = doc.xpath("/cda:ClinicalDocument/cda:component/cda:structuredBody/cda:component/cda:section/cda:entry/cda:organizer/cda:templateId[@root='2.16.840.1.113883.10.20.24.3.97']") + measure_ids = [] + nodes.each { |node| measure_ids << node.next_element["extension"] } + measure_ids + end + def gen_pop self.generate_population end @@ -31,25 +71,40 @@ def calculate_expected_results end def generate_records - min_set = PatientPopulation.min_coverage(self.measure_ids, self.bundle) - p_ids = min_set[:minimal_set] - overflow = min_set[:overflow] - all = p_ids + overflow - randomization_ids = all - while p_ids.length < 5 && overflow.length != 0 + if @uploaded_patient_xml_strings != nil + @uploaded_patient_xml_strings.each do |ps| + pr = HealthDataStandards::Import::BulkRecordImporter.import_and_return_unsaved_record(ps) + pr["test_id"] = self.id + pr.save + end + # ROGTODO: need to do the medical_record_assigner part? + else + min_set = PatientPopulation.min_coverage(self.measure_ids, self.bundle) + p_ids = min_set[:minimal_set] + print "minimal ids:\n" + print p_ids.length.to_s() + "\n" + p_ids.each { |pid| print pid + "\n" } + print "\n" + overflow = min_set[:overflow] + print "overflow length: " + overflow.length.to_s() + "\n" + all = p_ids + overflow + randomization_ids = all + while p_ids.length < 5 && overflow.length != 0 p_ids << overflow.sample - end - #randomly pick a number of other patients to give to the vendor + end + #randomly pick a number of other patients to give to the vendor - # do this synchronously because it does not take long - # p_ids = Record.where(:test_id=>nil, :type=>"ep").collect{|p| p.medical_record_number} - pcj = Cypress::PopulationCloneJob.new({'patient_ids' =>p_ids, 'test_id' => self.id, "randomize_names"=> true, "randomization_ids" => randomization_ids}) - pcj.perform + # do this synchronously because it does not take long + # p_ids = Record.where(:test_id=>nil, :type=>"ep").collect{|p| p.medical_record_number} + pcj = Cypress::PopulationCloneJob.new({'patient_ids' =>p_ids, 'test_id' => self.id, "randomize_names"=> true, "randomization_ids" => randomization_ids}) + pcj.perform - self.records.each do |r| - r.medical_record_assigner = "Cypress" if r.medical_record_assigner.nil? - r.save! + self.records.each do |r| + r.medical_record_assigner = "Cypress" if r.medical_record_assigner.nil? + r.save! + end end + #now calculate the expected results self.calculate end diff --git a/app/views/products/show.html.erb b/app/views/products/show.html.erb index 8255f5f47..5a4c0e7f3 100644 --- a/app/views/products/show.html.erb +++ b/app/views/products/show.html.erb @@ -1,11 +1,52 @@ <%= javascript 'products' %> + + +
| <%= f.file_field :test_zip, accept: "application/zip" %> | + /> + <%= hidden_field_tag(:type, "CalculatedProductTest") %> + <%-# ROGTODO: don't hard-code bundle id -%> + <%= hidden_field_tag(:bundle_id, "55afb5ad32393704ab000000") %> +
| Give the test a name: | +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Performance measures and related data specifications (the \"Measures\") are copyrighted by\nthe noted quality measure providers as indicated in the applicable Measure. Coding\nvocabularies are owned by their copyright owners. By using the Measures, a user\n(\"User\") agrees to these Terms of Use. Measures are not clinical guidelines and do not\nestablish a standard of medical care and quality measure providers are not responsible\nfor any use of or reliance on the Measures.
\n\nTHE MEASURES AND SPECIFICATIONS ARE PROVIDED \"AS IS\" WITHOUT ANY WARRANTY OF\nANY KIND, AND ANY AND ALL IMPLIED WARRANTIES ARE HEREBY DISCLAIMED, INCLUDING ANY\nWARRANTY OF NON-INFRINGEMENT, ACCURACY, MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE. NO QUALITY MEASURE PROVIDER, NOR ANY OF THEIR TRUSTEES, DIRECTORS, MEMBERS,\nAFFILIATES, OFFICERS, EMPLOYEES, SUCCESSORS AND/OR ASSIGNS WILL BE LIABLE TO YOU FOR\nANY DIRECT, INDIRECT, SPECIAL, EXEMPLARY, INCIDENTAL, PUNITIVE, AND/OR CONSEQUENTIAL\nDAMAGE OF ANY KIND, IN CONTRACT, TORT OR OTHERWISE, IN CONNECTION WITH THE USE OF THE\nPOPHEALTH TOOL OR THE MEASURES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH LOSS OR DAMAGE.\n
\n\nThe Measures are licensed to a User for the limited purpose of using, reproducing and\ndistributing the Measures with the popHealth Tool as delivered to User, without any\nmodification, for commercial and noncommercial uses, but such uses are only permitted\nif the copies of the Measures contain this complete Copyright, Disclaimer and Terms\nof Use. Users of the Measures may not alter, enhance, or otherwise modify the Measures.
\n\nNOT A CONTRIBUTION - The Measures, including specifications and coding,\nas used in the popHealth Tool, are not a contribution under the Apache license. Coding\nin the Measures is provided for convenience only and necessary licenses for use should\nbe obtained from the copyright owners. Current Procedural Terminology \n(CPT®) © 2004-2010 American Medical Association. \nLOINC® © 2004 Regenstrief Institute,\nInc. SNOMED Clinical Terms® \n(SNOMED CT®) © 2004-2010 International Health\nTerminology Standards Development Organization.
", - "extensions" : [ - "map_reduce_utils", - "underscore_min", - "childhood_immunization", - "chlamydia_common", - "asthma_common", - "aod_treatment", - "weight_management_utils", - "misc_utils", - "diabetes_utils", - "cardiac_utils" - ], - "smoking_gun_capable" : true, - "active" : true, - "effective_date" : 1293840000, - "measure_period_start" : 1293840000, - "measures" : [ - ] -} diff --git a/test/fixtures/bundles/installed_mpl.json b/test/fixtures/bundles/installed_mpl.json deleted file mode 100644 index 8b89f729e..000000000 --- a/test/fixtures/bundles/installed_mpl.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "_id" : "4ffb43a61d41c803df000001", - "name" : "Meaningful Use Stage 1 Test Deck", - "version" : "1.0.3", - "effective_date" : 1293840000, - "measure_period_start": 1293840000 -} - diff --git a/test/fixtures/product_tests/test_with_all_eye_measures.zip b/test/fixtures/product_tests/test_with_all_eye_measures.zip new file mode 100644 index 000000000..f98ab3b15 Binary files /dev/null and b/test/fixtures/product_tests/test_with_all_eye_measures.zip differ diff --git a/test/unit/tests/calculated_product_test_test.rb b/test/unit/tests/calculated_product_test_test.rb index befc53b95..5c823a136 100644 --- a/test/unit/tests/calculated_product_test_test.rb +++ b/test/unit/tests/calculated_product_test_test.rb @@ -82,6 +82,11 @@ class CalculatedProductTestTest < ActiveSupport::TestCase assert te.execution_errors.empty?, "should be no errors for good cat I archive" end + test "should create a ptest from an uploaded zip" do + test_zip = Rack::Test::UploadedFile.new(File.new(File.join(Rails.root, 'test/fixtures/product_tests/test_with_all_eye_measures.zip')), "application/zip") + assert test_zip != nil, "should upload the zip" + end + test "should cause error when stratifications are missing" do ptest = ProductTest.find("51703a6a3054cf8439000044") xml = Rack::Test::UploadedFile.new(File.new(File.join(Rails.root, 'test/fixtures/qrda/ep_test_qrda_cat3_missing_stratification.xml')), "application/xml")