diff --git a/.gitignore b/.gitignore index e773938..acbe4f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,13 @@ .bundle db/*.sqlite3 -log/*.log +log/* tmp/ .sass-cache/ .DS_Store doc/patient-api coverage.data coverage/ +.idea +util/files/ +Provider_Hash.txt +nagios-nrpe-support/tmp/ diff --git a/.travis.yml b/.travis.yml index b7f5d1f..25b5b81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,11 @@ language: ruby rvm: - - 1.9.2 + - 1.9.3 branches: only: - master - - develop +services: + - mongodb notifications: - email: - recipients: - - healthcare-ci@googlegroups.com - on_failure: change \ No newline at end of file + email: false +script: bundle exec rake test:units test:functionals test:integration diff --git a/Gemfile b/Gemfile index b166b93..a014ff3 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,6 @@ -source 'http://rubygems.org' -#gem 'java-query-gateway', '0.1', :git =>"http://github.com/rdingwell/java-hquery-executor.git", :platforms => :jruby -gem 'rails', '~> 3.2.1' +source 'https://rubygems.org' + +gem 'rails' gem 'jruby-openssl', :platforms => :jruby group :assets do gem 'sass-rails' @@ -11,16 +11,19 @@ end gem 'daemons' gem 'jquery-rails' -gem "mongoid", "~> 2.0" -gem "bson_ext", "~> 1.3", :platforms => :mri +gem 'mongoid' -gem 'delayed_job_mongoid', '~> 1.0.8' +gem 'delayed_job' +gem 'delayed_job_mongoid' -gem "hquery-patient-api", :git => 'http://github.com/hquery/patientapi.git', :tag => 'V0.3' -gem "health-data-standards", :git => 'http://github.com/projectcypress/health-data-standards.git', :branch => 'develop' -gem "hqmf2js", :git => 'http://github.com/hquery/hqmf2js.git', :tag => 'V0.3' +gem 'hquery-patient-api', :git => 'http://github.com/scoophealth/patientapi.git', :branch => 'master' +#gem 'hquery-patient-api', path: '../patientapi' +gem "health-data-standards", :git => 'http://github.com/scoophealth/health-data-standards.git', :branch => 'master' +#gem 'health-data-standards', path: '../health-data-standards' +#gem "health-data-standards", :git => 'http://github.com/scoophealth/health-data-standards.git', :branch => 'scoop-develop' +gem "hqmf2js", :git => 'http://github.com/scoophealth/hqmf2js.git', :branch => 'scoop-develop' #gem 'hqmf2js', path: '../hqmf2js' -gem 'hqmf-parser', :git => 'https://github.com/hquery/hqmf-parser.git', :tag => 'V0.3' +gem 'hqmf-parser', :git => 'http://github.com/scoophealth/hqmf-parser.git', :branch => 'scoop-develop' gem 'coderay' @@ -30,10 +33,10 @@ gem 'pry' group :test do # Pretty printed test output - gem 'minitest' + gem 'minitest', '< 5.0.0' gem 'turn', :require => false gem 'cover_me', '>= 1.0.0.rc6', :platforms => :ruby - gem 'factory_girl', '1.3.3' + gem 'factory_girl' gem 'awesome_print', :require => 'ap' gem 'mocha', :require => false gem 'therubyracer', :platforms => :ruby @@ -41,3 +44,7 @@ group :test do end +#group :production do +# gem 'thin' +#end + diff --git a/Gemfile.lock b/Gemfile.lock index d551b59..d097852 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,183 +1,187 @@ GIT - remote: http://github.com/hquery/hqmf2js.git - revision: cc1936810085fa43542c351e92765677976cfd1f - tag: V0.3 + remote: http://github.com/scoophealth/health-data-standards.git + revision: 475fcb7cd48c9938e10ff3ffdcb40c59bae7ad6f + branch: master specs: - hqmf2js (0.1.0) - coffee-script (~> 2.2.0) - nokogiri (~> 1.5.2) - sprockets (~> 2.1.2) - tilt (~> 1.3.3) + health-data-standards (2.1.4) + builder (~> 3.0.0) + erubis (~> 2.7.0) + mongoid (~> 3.0.6) + nokogiri (~> 1.5.5) + rest-client (~> 1.6.7) + uuid (~> 2.3.5) GIT - remote: http://github.com/hquery/patientapi.git - revision: b81d65013444263b0a6c8db1516b339e73bf1e9a - tag: V0.3 + remote: http://github.com/scoophealth/hqmf-parser.git + revision: 7255b22df28004a00721209b8a9f3ff708c2028d + branch: scoop-develop specs: - hquery-patient-api (0.1.0) + hqmf-parser (1.1.0) + google-spreadsheet-ruby (= 0.1.8) + roo (= 1.10.1) + rubyzip + spreadsheet (= 0.6.8) GIT - remote: http://github.com/projectcypress/health-data-standards.git - revision: 41354a3fb14530ded02f5a35fdefac2aec3fa665 - branch: develop + remote: http://github.com/scoophealth/hqmf2js.git + revision: cfc4af98da3f516899c9614ecd673d7f23e9e461 + branch: scoop-develop specs: - health-data-standards (1.0.1) - builder (~> 3.0.0) - erubis (~> 2.6) - mongoid (~> 2.4.2) - nokogiri (>= 1.4.4) - uuid (~> 2.3.4) + hqmf2js (0.1.0) + coffee-script (~> 2.2.0) + nokogiri (~> 1.5.10) + sprockets (~> 2.2.2) + tilt (~> 1.4.1) GIT - remote: https://github.com/hquery/hqmf-parser.git - revision: 8cbd14029c76c2c27409366528c59d0c34bddcc4 - tag: V0.3 + remote: http://github.com/scoophealth/patientapi.git + revision: c38c5f72e0ea4801d2e5cb86c20bd04b544cc67a + branch: master specs: - hqmf-parser (0.0.1) - google-spreadsheet-ruby (= 0.1.8) - roo (= 1.10.1) - rubyzip - spreadsheet (= 0.6.8) + hquery-patient-api (1.0.5) GEM - remote: http://rubygems.org/ + remote: https://rubygems.org/ specs: - actionmailer (3.2.2) - actionpack (= 3.2.2) - mail (~> 2.4.0) - actionpack (3.2.2) - activemodel (= 3.2.2) - activesupport (= 3.2.2) + actionmailer (3.2.13) + actionpack (= 3.2.13) + mail (~> 2.5.3) + actionpack (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) builder (~> 3.0.0) erubis (~> 2.7.0) - journey (~> 1.0.1) - rack (~> 1.4.0) - rack-cache (~> 1.1) + journey (~> 1.0.4) + rack (~> 1.4.5) + rack-cache (~> 1.2) rack-test (~> 0.6.1) - sprockets (~> 2.1.2) - activemodel (3.2.2) - activesupport (= 3.2.2) + sprockets (~> 2.2.1) + activemodel (3.2.13) + activesupport (= 3.2.13) builder (~> 3.0.0) - activerecord (3.2.2) - activemodel (= 3.2.2) - activesupport (= 3.2.2) + activerecord (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activeresource (3.2.2) - activemodel (= 3.2.2) - activesupport (= 3.2.2) - activesupport (3.2.2) - i18n (~> 0.6) + activeresource (3.2.13) + activemodel (= 3.2.13) + activesupport (= 3.2.13) + activesupport (3.2.13) + i18n (= 0.6.1) multi_json (~> 1.0) - ansi (1.4.2) + ansi (1.4.3) arel (3.0.2) - awesome_print (1.0.2) - bson (1.6.0) - bson_ext (1.6.0) - bson (= 1.6.0) - builder (3.0.0) + awesome_print (1.1.0) + builder (3.0.4) choice (0.1.6) - coderay (1.0.5) + coderay (1.0.9) coffee-rails (3.2.2) coffee-script (>= 2.2.0) railties (~> 3.2.0) coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.3.3) - configatron (2.9.0) + coffee-script-source (1.6.3) + configatron (2.13.0) yamler (>= 0.1.0) cover_me (1.2.0) configatron hashie - daemons (1.1.4) - delayed_job (3.0.1) + daemons (1.1.9) + delayed_job (3.0.5) activesupport (~> 3.0) - delayed_job_mongoid (1.0.8) - delayed_job (~> 3.0.0) - mongoid (>= 2.0) + delayed_job_mongoid (2.0.0) + delayed_job (~> 3.0) + mongoid (~> 3.0) erubis (2.7.0) execjs (1.4.0) multi_json (~> 1.0) - factory_girl (1.3.3) - faraday (0.8.4) + factory_girl (4.2.0) + activesupport (>= 3.0.0) + faraday (0.8.7) multipart-post (~> 1.1) google-spreadsheet-ruby (0.1.8) nokogiri (>= 1.4.3.1) oauth (>= 0.3.6) oauth2 (>= 0.5.0) - hashie (1.2.0) - hike (1.2.1) - httpauth (0.1) - i18n (0.6.0) + hashie (2.0.5) + hike (1.2.3) + httpauth (0.2.0) + i18n (0.6.1) journey (1.0.4) - jquery-rails (2.1.1) - railties (>= 3.1.0, < 5.0) - thor (~> 0.14) - json (1.7.5) - jwt (0.1.5) - multi_json (>= 1.0) - kramdown (0.13.5) - libv8 (3.3.10.4) + jquery-rails (3.0.2) + railties (>= 3.0, < 5.0) + thor (>= 0.14, < 2.0) + json (1.8.0) + jwt (0.1.8) + multi_json (>= 1.5) + kramdown (1.1.0) + libv8 (3.11.8.17) log4r (1.1.10) - macaddr (1.6.1) - systemu (~> 2.5.0) - mail (2.4.4) - i18n (>= 0.4.0) + macaddr (1.7.1) + systemu (~> 2.6.2) + mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) metaclass (0.0.1) - method_source (0.7.0) - mime-types (1.18) - minitest (2.11.2) - mocha (0.10.4) + method_source (0.8.1) + mime-types (1.23) + minitest (4.7.5) + mocha (0.14.0) metaclass (~> 0.0.1) - mongo (1.6.0) - bson (= 1.6.0) - mongoid (2.4.12) + mongoid (3.0.23) activemodel (~> 3.1) - mongo (<= 1.6.2) + moped (~> 1.2) + origin (~> 1.0) tzinfo (~> 0.3.22) - multi_json (1.3.6) - multipart-post (1.1.5) - nokogiri (1.5.5) - oauth (0.4.6) - oauth2 (0.8.0) + moped (1.5.0) + multi_json (1.7.7) + multi_xml (0.5.4) + multipart-post (1.2.0) + nokogiri (1.5.10) + oauth (0.4.7) + oauth2 (0.9.2) faraday (~> 0.8) - httpauth (~> 0.1) + httpauth (~> 0.2) jwt (~> 0.1.4) multi_json (~> 1.0) + multi_xml (~> 0.5) rack (~> 1.2) + origin (1.1.0) polyglot (0.3.3) - pry (0.9.8.2) + pry (0.9.12.2) coderay (~> 1.0.5) - method_source (~> 0.7) - slop (>= 2.4.4, < 3) - rack (1.4.1) + method_source (~> 0.8) + slop (~> 3.4) + rack (1.4.5) rack-cache (1.2) rack (>= 0.4) - rack-ssl (1.3.2) + rack-ssl (1.3.3) rack - rack-test (0.6.1) + rack-test (0.6.2) rack (>= 1.0) - rails (3.2.2) - actionmailer (= 3.2.2) - actionpack (= 3.2.2) - activerecord (= 3.2.2) - activeresource (= 3.2.2) - activesupport (= 3.2.2) + rails (3.2.13) + actionmailer (= 3.2.13) + actionpack (= 3.2.13) + activerecord (= 3.2.13) + activeresource (= 3.2.13) + activesupport (= 3.2.13) bundler (~> 1.0) - railties (= 3.2.2) - railties (3.2.2) - actionpack (= 3.2.2) - activesupport (= 3.2.2) + railties (= 3.2.13) + railties (3.2.13) + actionpack (= 3.2.13) + activesupport (= 3.2.13) rack-ssl (~> 1.3.2) rake (>= 0.8.7) rdoc (~> 3.4) - thor (~> 0.14.6) - rake (0.9.2.2) - rdoc (3.12) + thor (>= 0.14.6, < 2.0) + rake (10.1.0) + rdoc (3.12.2) json (~> 1.4) + ref (1.0.5) + rest-client (1.6.9) + mime-types (~> 1.16) roo (1.10.1) choice (>= 0.1.4) google-spreadsheet-ruby (>= 0.1.5) @@ -185,37 +189,39 @@ GEM rubyzip (>= 0.9.4) spreadsheet (> 0.6.4) todonotes (>= 0.1.0) - ruby-ole (1.2.11.4) + ruby-ole (1.2.11.7) rubyzip (0.9.9) - sass (3.1.15) - sass-rails (3.2.4) + sass (3.2.9) + sass-rails (3.2.6) railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) - slop (2.4.4) + slop (3.4.5) spreadsheet (0.6.8) ruby-ole (>= 1.0) - sprockets (2.1.3) + sprockets (2.2.2) hike (~> 1.2) + multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - systemu (2.5.2) - therubyracer (0.9.10) - libv8 (~> 3.3.10) - thor (0.14.6) - tilt (1.3.3) - todonotes (0.1.0) + systemu (2.6.5) + therubyracer (0.11.4) + libv8 (~> 3.11.8.12) + ref + thor (0.18.1) + tilt (1.4.1) + todonotes (0.1.1) log4r - treetop (1.4.10) + treetop (1.4.14) polyglot polyglot (>= 0.3.1) - turn (0.9.3) + turn (0.9.6) ansi - tzinfo (0.3.33) - uglifier (1.2.3) + tzinfo (0.3.37) + uglifier (2.1.1) execjs (>= 0.3.0) - multi_json (>= 1.0.2) - uuid (2.3.5) + multi_json (~> 1.0, >= 1.0.2) + uuid (2.3.8) macaddr (~> 1.0) yamler (0.1.0) @@ -224,13 +230,13 @@ PLATFORMS DEPENDENCIES awesome_print - bson_ext (~> 1.3) coderay coffee-rails cover_me (>= 1.0.0.rc6) daemons - delayed_job_mongoid (~> 1.0.8) - factory_girl (= 1.3.3) + delayed_job + delayed_job_mongoid + factory_girl health-data-standards! hqmf-parser! hqmf2js! @@ -238,11 +244,11 @@ DEPENDENCIES jquery-rails jruby-openssl kramdown - minitest + minitest (< 5.0.0) mocha - mongoid (~> 2.0) + mongoid pry - rails (~> 3.2.1) + rails sass-rails therubyracer therubyrhino diff --git a/README b/README deleted file mode 100644 index 7c36f23..0000000 --- a/README +++ /dev/null @@ -1,261 +0,0 @@ -== Welcome to Rails - -Rails is a web-application framework that includes everything needed to create -database-backed web applications according to the Model-View-Control pattern. - -This pattern splits the view (also called the presentation) into "dumb" -templates that are primarily responsible for inserting pre-built data in between -HTML tags. The model contains the "smart" domain objects (such as Account, -Product, Person, Post) that holds all the business logic and knows how to -persist themselves to a database. The controller handles the incoming requests -(such as Save New Account, Update Product, Show Post) by manipulating the model -and directing data to the view. - -In Rails, the model is handled by what's called an object-relational mapping -layer entitled Active Record. This layer allows you to present the data from -database rows as objects and embellish these data objects with business logic -methods. You can read more about Active Record in -link:files/vendor/rails/activerecord/README.html. - -The controller and view are handled by the Action Pack, which handles both -layers by its two parts: Action View and Action Controller. These two layers -are bundled in a single package due to their heavy interdependence. This is -unlike the relationship between the Active Record and Action Pack that is much -more separate. Each of these packages can be used independently outside of -Rails. You can read more about Action Pack in -link:files/vendor/rails/actionpack/README.html. - - -== Getting Started - -1. At the command prompt, create a new Rails application: - rails new myapp (where myapp is the application name) - -2. Change directory to myapp and start the web server: - cd myapp; rails server (run with --help for options) - -3. Go to http://localhost:3000/ and you'll see: - "Welcome aboard: You're riding Ruby on Rails!" - -4. Follow the guidelines to start developing your application. You can find -the following resources handy: - -* The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html -* Ruby on Rails Tutorial Book: http://www.railstutorial.org/ - - -== Debugging Rails - -Sometimes your application goes wrong. Fortunately there are a lot of tools that -will help you debug it and get it back on the rails. - -First area to check is the application log files. Have "tail -f" commands -running on the server.log and development.log. Rails will automatically display -debugging and runtime information to these files. Debugging info will also be -shown in the browser on requests from 127.0.0.1. - -You can also log your own messages directly into the log file from your code -using the Ruby logger class from inside your controllers. Example: - - class WeblogController < ActionController::Base - def destroy - @weblog = Weblog.find(params[:id]) - @weblog.destroy - logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!") - end - end - -The result will be a message in your log file along the lines of: - - Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1! - -More information on how to use the logger is at http://www.ruby-doc.org/core/ - -Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are -several books available online as well: - -* Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe) -* Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide) - -These two books will bring you up to speed on the Ruby language and also on -programming in general. - - -== Debugger - -Debugger support is available through the debugger command when you start your -Mongrel or WEBrick server with --debugger. This means that you can break out of -execution at any point in the code, investigate and change the model, and then, -resume execution! You need to install ruby-debug to run the server in debugging -mode. With gems, use sudo gem install ruby-debug. Example: - - class WeblogController < ActionController::Base - def index - @posts = Post.all - debugger - end - end - -So the controller will accept the action, run the first line, then present you -with a IRB prompt in the server window. Here you can do things like: - - >> @posts.inspect - => "[#nil, "body"=>nil, "id"=>"1"}>, - #"Rails", "body"=>"Only ten..", "id"=>"2"}>]" - >> @posts.first.title = "hello from a debugger" - => "hello from a debugger" - -...and even better, you can examine how your runtime objects actually work: - - >> f = @posts.first - => #nil, "body"=>nil, "id"=>"1"}> - >> f. - Display all 152 possibilities? (y or n) - -Finally, when you're ready to resume execution, you can enter "cont". - - -== Console - -The console is a Ruby shell, which allows you to interact with your -application's domain model. Here you'll have all parts of the application -configured, just like it is when the application is running. You can inspect -domain models, change values, and save to the database. Starting the script -without arguments will launch it in the development environment. - -To start the console, run rails console from the application -directory. - -Options: - -* Passing the -s, --sandbox argument will rollback any modifications - made to the database. -* Passing an environment name as an argument will load the corresponding - environment. Example: rails console production. - -To reload your controllers and models after launching the console run -reload! - -More information about irb can be found at: -link:http://www.rubycentral.org/pickaxe/irb.html - - -== dbconsole - -You can go to the command line of your database directly through rails -dbconsole. You would be connected to the database with the credentials -defined in database.yml. Starting the script without arguments will connect you -to the development database. Passing an argument will connect you to a different -database, like rails dbconsole production. Currently works for MySQL, -PostgreSQL and SQLite 3. - -== Description of Contents - -The default directory structure of a generated Ruby on Rails application: - - |-- app - | |-- assets - | |-- images - | |-- javascripts - | `-- stylesheets - | |-- controllers - | |-- helpers - | |-- mailers - | |-- models - | `-- views - | `-- layouts - |-- config - | |-- environments - | |-- initializers - | `-- locales - |-- db - |-- doc - |-- lib - | `-- tasks - |-- log - |-- public - |-- script - |-- test - | |-- fixtures - | |-- functional - | |-- integration - | |-- performance - | `-- unit - |-- tmp - | |-- cache - | |-- pids - | |-- sessions - | `-- sockets - `-- vendor - |-- assets - `-- stylesheets - `-- plugins - -app - Holds all the code that's specific to this particular application. - -app/assets - Contains subdirectories for images, stylesheets, and JavaScript files. - -app/controllers - Holds controllers that should be named like weblogs_controller.rb for - automated URL mapping. All controllers should descend from - ApplicationController which itself descends from ActionController::Base. - -app/models - Holds models that should be named like post.rb. Models descend from - ActiveRecord::Base by default. - -app/views - Holds the template files for the view that should be named like - weblogs/index.html.erb for the WeblogsController#index action. All views use - eRuby syntax by default. - -app/views/layouts - Holds the template files for layouts to be used with views. This models the - common header/footer method of wrapping views. In your views, define a layout - using the layout :default and create a file named default.html.erb. - Inside default.html.erb, call <% yield %> to render the view using this - layout. - -app/helpers - Holds view helpers that should be named like weblogs_helper.rb. These are - generated for you automatically when using generators for controllers. - Helpers can be used to wrap functionality for your views into methods. - -config - Configuration files for the Rails environment, the routing map, the database, - and other dependencies. - -db - Contains the database schema in schema.rb. db/migrate contains all the - sequence of Migrations for your schema. - -doc - This directory is where your application documentation will be stored when - generated using rake doc:app - -lib - Application specific libraries. Basically, any kind of custom code that - doesn't belong under controllers, models, or helpers. This directory is in - the load path. - -public - The directory available for the web server. Also contains the dispatchers and the - default HTML files. This should be set as the DOCUMENT_ROOT of your web - server. - -script - Helper scripts for automation and generation. - -test - Unit and functional tests along with fixtures. When using the rails generate - command, template test files will be generated for you and placed in this - directory. - -vendor - External libraries that the application depends on. Also includes the plugins - subdirectory. If the app has frozen rails, those gems also go here, under - vendor/rails/. This directory is in the load path. diff --git a/README.md b/README.md index 3f7f411..f505a05 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -hQuery +hQuery [![travis](https://secure.travis-ci.org/scoophealth/query-gateway.png?branch=master)](http://travis-ci.org/scoophealth/query-gateway) ========= The query gateway is a web based application that provides the back end for executing queries. @@ -14,15 +14,20 @@ hQuery will also run on Windows, however, there are some minor limitations to fu Dependencies ------------ -* Ruby = 1.9.2 -* Rails 3.1 +* Ruby = 1.9.3 +* Rails >= 3.1 * MongoDB >= 1.8.1 Install Instructions -------------------- See the query composer for installation instructions for both the composer and gateway - http://github.com/hquery + [https://github.com/scoophealth](https://github.com/scoophealth) + +Quick Start +----------- + +Assuming the ruby environment has already been set up, you can use the runme.sh file to start a normal gateway server instance, and the secrunme.sh file to start a secure gateway server instance. License ------- @@ -44,4 +49,4 @@ limitations under the License. Project Practices ----------------- -Please try to follow our [Coding Style Guides](http://github.com/eedrummer/styleguide). Additionally, we will be using git in a pattern similar to [Vincent Driessen's workflow](http://nvie.com/posts/a-successful-git-branching-model/). While feature branches are encouraged, they are not required to work on the project. \ No newline at end of file +Please try to follow our [Coding Style Guides](http://github.com/eedrummer/styleguide). Additionally, we will be using git in a pattern similar to [Vincent Driessen's workflow](http://nvie.com/posts/a-successful-git-branching-model/). While feature branches are encouraged, they are not required to work on the project. diff --git a/README.rdoc b/README.rdoc index 05d537d..0a09c3c 100644 --- a/README.rdoc +++ b/README.rdoc @@ -13,10 +13,10 @@ hQuery will also run on Windows, however, there are some minor limitations to fu = Dependencies -* Ruby = 1.9.2 -* Rails 3.1 -* MongoDB >= 1.8.1 +* Ruby = 1.9.3 +* Rails >= 3.1 +* MongoDB >= 1.8.1+ = End-to-end Install Instructions See the query composer for installation instructions for both the composer and gateway - http://github \ No newline at end of file + http://github diff --git a/README.scoop b/README.scoop new file mode 100644 index 0000000..63ffb01 --- /dev/null +++ b/README.scoop @@ -0,0 +1,20 @@ +Get the source code for the gateway. Do this with the following: + +cd ~ + +git clone -b scoop-develop git://github.com/scoophealth/query-gateway.git + +Afterwards, go into the new directory, install, seed, and start the server. + +cd query-gateway + +bundle install + +bundle exec rake db:seed + +mkdir -p tmp/pids + +The following commands starts the server on port 3001. + +bundle exec script/delayed_job start +bundle exec rails server -p 3001 diff --git a/README.scoop-test b/README.scoop-test new file mode 100644 index 0000000..fe23164 --- /dev/null +++ b/README.scoop-test @@ -0,0 +1,17 @@ +To run the unit, functional and integration tests, from the root directory +of the repository execute + + rake test + +When changes are made to the E2E export documents requiring modifications +of the health-data-standards E2E importer code, or the health-data-standards +E2E importer code is changed for any other reason, the records stored in +mongod are likely to change. When this happens, the file +test/fixtures/scoop-records.json will need to be updated. + +Use util/relay-service.rb to load the updated test patient records into +the mongod. Then export these mongod test patient records using: + +mongoexport -d query_gateway_development -c records > /tmp/scoop-records.json + +Use the export to update ./test/fixtures/scoop-records.json diff --git a/app/assets/javascripts/sysinfo.js.coffee b/app/assets/javascripts/sysinfo.js.coffee new file mode 100644 index 0000000..7615679 --- /dev/null +++ b/app/assets/javascripts/sysinfo.js.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/ diff --git a/app/assets/stylesheets/sysinfo.css.scss b/app/assets/stylesheets/sysinfo.css.scss new file mode 100644 index 0000000..2fa38c3 --- /dev/null +++ b/app/assets/stylesheets/sysinfo.css.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the sysinfo controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index cda91a5..372cfba 100644 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -1,6 +1,7 @@ class QueriesController < ApplicationController def index if stale?(:last_modified => Query.last_query_update.utc) + Query.create_indexes # ensures the indexes are created, does nothing if they already exist @queries = Query.desc(:updated_at) respond_to do |format| format.atom @@ -48,7 +49,7 @@ def show if stale?(:last_modified => @query.updated_at.utc) @qh = @query.attributes @qh.delete('delayed_job_id') - if @query.status == :complete + if @query.status == :complete and @query.result != nil @qh['result_url'] = result_url(@query.result) end respond_to do |format| diff --git a/app/controllers/records_controller.rb b/app/controllers/records_controller.rb index 85054c3..2496e44 100644 --- a/app/controllers/records_controller.rb +++ b/app/controllers/records_controller.rb @@ -2,13 +2,80 @@ class RecordsController < ApplicationController def create xml_file = params[:content].read doc = Nokogiri::XML(xml_file) - doc.root.add_namespace_definition('cda', 'urn:hl7-org:v3') - pi = HealthDataStandards::Import::C32::PatientImporter.instance - patient = pi.parse_c32(doc) - - patient.save! - - render :text => 'Patient imported', :status => 201 + root_element_name = doc.root.name + if root_element_name == 'ClinicalDocument' + doc.root.add_namespace_definition('cda', 'urn:hl7-org:v3') + #document_type = doc.at_xpath('/cda:ClinicalDocument/cda:templateId')['root'] + document_type = doc.at_xpath('/cda:ClinicalDocument/cda:realmCode')['code'] + # check the specific flavour of cda + # E2E + if document_type == 'CA-BC' || document_type == 'CA' + pi = HealthDataStandards::Import::E2E::PatientImporter.instance + patient = pi.parse_e2e(doc) + # By specifying the _id field we create a new document when a record + # with that _id field doesn't already exist in the collection. If + # a record with the same _id field already exists, it is updated + # with the new document. For details see + # http://docs.mongodb.org/manual/reference/method/db.collection.save/ + patient_id = OpenSSL::Digest::SHA224.new + hin_id = OpenSSL::Digest::SHA224.new + first_id = OpenSSL::Digest::SHA224.new + last_id = OpenSSL::Digest::SHA224.new + if !patient.medical_record_number.nil? && !patient.medical_record_number.empty? + patient_id << patient.medical_record_number.upcase + #patient.medical_record_number = "" # remove HIN + hin_id << patient.medical_record_number.upcase + patient.medical_record_number = Base64.strict_encode64(hin_id.digest) + end + if !patient.first.nil? && !patient.first.empty? + patient_id << patient.first.upcase + #patient.first = "" # remove first name + first_id << patient.first.upcase + patient.first = Base64.strict_encode64(first_id.digest) + end + if !patient.last.nil? && !patient.last.empty? + patient_id << patient.last.upcase + #patient.last = "" # remove last name + last_id << patient.last.upcase + patient.last = Base64.strict_encode64(last_id.digest) + end + if !patient.birthdate.nil? && !patient.birthdate.to_s.empty? + patient_id << patient.birthdate.to_s + end + if !patient.gender.nil? && !patient.gender.empty? + patient_id << patient.gender.upcase + end + patient[:hash_id] = Base64.strict_encode64(patient_id.digest) + # Use EMR instance demographic table primary key as unique _id in patient records collection + emr_demographics_key = patient.emr_demographics_primary_key + if emr_demographics_key + patient[:_id] = emr_demographics_key + else + patient[:_id] = patient[:hash_id] + end + ### Example of how to capture E2E document for debugging purposes + ### if patient[:_id] == '149' + ### File.open("#{Rails.root}/log/149.xml", 'wb') { |file| file.write(xml_file) } + ### end + # patient.save! isn't working as documented, don't know why + # appears that it should but upsert does what we need. See + # http://mongoid.org/en/mongoid/docs/persistence.html + patient.upsert + render :text => 'E2E Document imported', :status => 201 + # C32 + else + pi = HealthDataStandards::Import::C32::PatientImporter.instance + patient = pi.parse_c32(doc) + patient.save! + render :text => 'C32 Patient imported', :status => 201 + end + else + render :text => 'Unknown XML Format', :status => 400 + end end + def destroy + Record.delete_all + render :text => 'All patients were deleted', :status => 200 + end end diff --git a/app/controllers/sysinfo_controller.rb b/app/controllers/sysinfo_controller.rb new file mode 100644 index 0000000..7c465da --- /dev/null +++ b/app/controllers/sysinfo_controller.rb @@ -0,0 +1,56 @@ +class SysinfoController < ApplicationController + + if defined?(Rails.root) + NAGIOS_PLUGINS = "#{Rails.root}/nagios-plugins" + else + NAGIOS_PLUGINS = File.dirname(__FILE__)+'/../../nagios-plugins' + end + + def load + textstr = `#{NAGIOS_PLUGINS}/check_load --warning='5.0,4.0,3.0' --critical='10.0,6.0,4.0'` + textstr += 'Status Code: ' + $?.exitstatus.to_s + "\n" + render :text => textstr, :status =>201 + end + + def users + textstr = `#{NAGIOS_PLUGINS}/check_users -w '5' -c '10'` + textstr += 'Status Code: ' + $?.exitstatus.to_s + "\n" + render :text => textstr, :status =>201 + end + + def diskspace + textstr = `#{NAGIOS_PLUGINS}/check_disk -w '20%' -c '10%' -e` + textstr += 'Status Code: ' + $?.exitstatus.to_s + "\n" + render :text => textstr, :status =>201 + end + + def mongo + # do nothing + end + + def processes + textstr = `#{NAGIOS_PLUGINS}/check_procs -w '250' -c '400'` + textstr += 'Status Code: ' + $?.exitstatus.to_s + "\n" + render :text => textstr, :status =>201 + end + + def swap + textstr = `#{NAGIOS_PLUGINS}/check_swap -w '95%' -c '90%'` + textstr += 'Status Code: ' + $?.exitstatus.to_s + "\n" + render :text => textstr, :status =>201 + end + + + def import + textstr = `#{NAGIOS_PLUGINS}/check_import.sh` + textstr += 'Status Code: ' + $?.exitstatus.to_s + "\n" + render :text => textstr, :status =>201 + end + + def tomcat + textstr = `#{NAGIOS_PLUGINS}/check_procs -w 1:1 -c 1:1 -u tomcat6 -a tomcat6` + textstr += 'Status Code: ' + $?.exitstatus.to_s + "\n" + render :text => textstr, :status =>201 + end + +end diff --git a/app/helpers/sysinfo_helper.rb b/app/helpers/sysinfo_helper.rb new file mode 100644 index 0000000..c054b55 --- /dev/null +++ b/app/helpers/sysinfo_helper.rb @@ -0,0 +1,2 @@ +module SysinfoHelper +end diff --git a/app/models/.gitkeep b/app/models/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/app/models/query.rb b/app/models/query.rb index 63b5585..4d624bf 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -18,6 +18,8 @@ class Query validates_presence_of :map validates_presence_of :reduce + + index({ updated_at: -1}) def status_change(new_status, message) self.status = new_status diff --git a/app/views/sysinfo/currentload.html.erb b/app/views/sysinfo/currentload.html.erb new file mode 100644 index 0000000..61d0ae2 --- /dev/null +++ b/app/views/sysinfo/currentload.html.erb @@ -0,0 +1,2 @@ +

Sysinfo#currentload

+

Find me in app/views/sysinfo/currentload.html.erb

diff --git a/app/views/sysinfo/currentusers.html.erb b/app/views/sysinfo/currentusers.html.erb new file mode 100644 index 0000000..8f864f5 --- /dev/null +++ b/app/views/sysinfo/currentusers.html.erb @@ -0,0 +1,2 @@ +

Sysinfo#currentusers

+

Find me in app/views/sysinfo/currentusers.html.erb

diff --git a/app/views/sysinfo/diskspace.html.erb b/app/views/sysinfo/diskspace.html.erb new file mode 100644 index 0000000..4d3f59f --- /dev/null +++ b/app/views/sysinfo/diskspace.html.erb @@ -0,0 +1,2 @@ +

Sysinfo#diskspace

+

Find me in app/views/sysinfo/diskspace.html.erb

diff --git a/app/views/sysinfo/mongo.html.erb b/app/views/sysinfo/mongo.html.erb new file mode 100644 index 0000000..5a584dd --- /dev/null +++ b/app/views/sysinfo/mongo.html.erb @@ -0,0 +1,2 @@ +

Sysinfo#mongo

+

Find me in app/views/sysinfo/mongo.html.erb

diff --git a/app/views/sysinfo/swap.html.erb b/app/views/sysinfo/swap.html.erb new file mode 100644 index 0000000..2459daa --- /dev/null +++ b/app/views/sysinfo/swap.html.erb @@ -0,0 +1,2 @@ +

Sysinfo#swap

+

Find me in app/views/sysinfo/swap.html.erb

diff --git a/app/views/sysinfo/totalprocesses.html.erb b/app/views/sysinfo/totalprocesses.html.erb new file mode 100644 index 0000000..6ac7ba3 --- /dev/null +++ b/app/views/sysinfo/totalprocesses.html.erb @@ -0,0 +1,2 @@ +

Sysinfo#totalprocesses

+

Find me in app/views/sysinfo/totalprocesses.html.erb

diff --git a/cert/README b/cert/README new file mode 100644 index 0000000..8e739d4 --- /dev/null +++ b/cert/README @@ -0,0 +1,53 @@ +# Change into the query-gateway root directory. Make a cert subdirectory. +cd $HOME/query-gateway && mkdir cert && cd cert +# +# Generate a self-signed certificate. You need to answer some questions. +# Most of them can be answered arbitrarily but it is important that the +# Common Name be accurate. For development and test purposes you can +# use something like *.localdomain to cover all hosts in localdomain. +# I used: +# Country Name (2 letter code) [GB]:CA +# State or Province Name (full name): British Columbia +# Locality Name (eg, city): Victoria +# Organization Name (eg, company): University of Victoria +# Organizational Unit Name (eg, section): Island Medical Program +# Common Name (eg, your name or your server's hostname): *.localdomain +# Email Address: scoophealth@googlegroups.com +# +# This will generate the certificate and key in a file named server.pem: +openssl req -new -x509 -keyout server.pem -out server.pem -nodes -days 365 +# +# Copy the self-signed certificate to query-gateway/cert/ca +# [The location and name can be changed but must match +# the entries in query-gateway/script/secure_rails.] +mkdir ca && cp server.pem ca/LeadLab_root_cert_TEST.pem && rm server.pem +# +# Note: We used *.localdomain for the "Common Name" when prompted +# for that information. For this to work, you will need an /etc/hosts +# file that maps IP addresses to entries in the localdomain. For instance, +# $ cat /etc/hosts +# 127.0.0.1 localhost localhost.localdomain +# 127.0.1.1 query-gateway query-gateway.localdomain +# 192.168.52.100 mysql-host mysql-host.localdomain +# 192.168.52.101 query-gateway0 query-gateway0.localdomain +# 192.168.52.102 query-composer query-composer.localdomain +# 192.168.52.103 query-gateway1 query-gateway1.localdomain +# +# Now find the hash of the self-signed certificate +# $ openssl x509 -hash -noout -in ../cert/ca/LeadLab_root_cert_TEST.pem +# +# 962a3564 +# +# Create a symbolic link from the self-signed certicate to a file in +# /etc/ssl/certs with name matching the hash with suffix '.0'. +# +# /etc/ssl/certs/962a3564.0 ->/home/vagrant/query-gateway/cert/ca/LeadLab_root_cert_TEST.pem +# +# For this particular self-signed certificate's hash, I did this: +# $ sudo ln -s /home/vagrant/query-gateway/cert/ca/LeadLab_root_cert_TEST.pem /etc/ssl/certs/962a3564.0 +# +# To start up the SSL secured version of query-gateway on port 3222 use: +# $ bundle exec script/delayed_job start +# $ bundle exec ruby script/secure_rails server -p 3222 +# To start the non-SSL secured version on port 3001 use: +# $ bundle exec rails server -p 3001 diff --git a/cert/ca/LeadLab_root_cert_TEST.pem b/cert/ca/LeadLab_root_cert_TEST.pem new file mode 100644 index 0000000..5af6e59 --- /dev/null +++ b/cert/ca/LeadLab_root_cert_TEST.pem @@ -0,0 +1,36 @@ +-----BEGIN PRIVATE KEY----- +MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANEKAbCsoweaNzb1 +An3rPTlF/8lypAz6zReIML6dBrquO/R1fHYrs1qdQCOf8rY3mFU+FCloSFIITiF+ +NeqsVzGAFwRbT2HIwCiWMepLvjumLxCPSfUZiz+yhgXjNnNLu4m+YzDlFJCmMDV+ +m0Q0ViKFyPzPINGVI0xtPFTKX1fpAgMBAAECgYBsdQepdfjkUeRB9F9Fm87ZL3Nm +Pr/VKC9O/U9lJq2+H/ZlgKuB2GynIB2OHkfcuP2lhJ8LWNrlDQAUqpoo1yApUydz +u98QLFw7+7V5B8igC+mxjImc9XGdWtB+/sAQk3aQuEMLskmpvZHkCgzIWylvRvmb +ATBFvethNnqRC5PrgQJBAPZvYoDub4nm9Lyb+7Pc8ZSKmmltngbYEFXhrld21WIn +wL95ZeiJqyleZxsXth86fSWd+Fgv8KmYYrw7DMjIibkCQQDZJwyy1tibX6nTaou5 +TYBVAvlTuYA5iVOh1Q/a9T/Ko/4/dX8lm/Lm7MrMRxqIGok1IIexNhsfloN/TUew +XJexAkArozupIw+jNr99qo1eozAwIn8HTj7ebWIvIwBxQny0nd92yHNwQviJIctW +M9OvIfdJMvjn/M076t0JAdfYshIZAkA4wy9blDN8sc3nmKM7ZdnU3vkjfIra/12g +INyLJK5vHtz345O/1frxiBYevbtetmkFPSKbHQSMBkELRr0liZ6RAkBzhur1fRhr +RjJR38o684Z4Sx0iflyWFVe/08EVXBqCaj6Bb9/unQmYC+dWhmJqAOUS/FiaEmvC +EaE6hG7QkARE +-----END PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIDVDCCAr2gAwIBAgIJAOWAnoqQBfNbMA0GCSqGSIb3DQEBBQUAMIHCMQswCQYD +VQQGEwJDQTEZMBcGA1UECAwQQnJpdGlzaCBDb2x1bWJpYTERMA8GA1UEBwwIVmlj +dG9yaWExHzAdBgNVBAoMFlVuaXZlcnNpdHkgb2YgVmljdG9yaWExHzAdBgNVBAsM +FklzbGFuZCBNZWRpY2FsIFByb2dyYW0xFjAUBgNVBAMMDSoubG9jYWxkb21haW4x +KzApBgkqhkiG9w0BCQEWHHNjb29waGVhbHRoQGdvb2dsZWdyb3Vwcy5jb20wHhcN +MTMwODI4MjAwMjEwWhcNMTQwODI4MjAwMjEwWjCBwjELMAkGA1UEBhMCQ0ExGTAX +BgNVBAgMEEJyaXRpc2ggQ29sdW1iaWExETAPBgNVBAcMCFZpY3RvcmlhMR8wHQYD +VQQKDBZVbml2ZXJzaXR5IG9mIFZpY3RvcmlhMR8wHQYDVQQLDBZJc2xhbmQgTWVk +aWNhbCBQcm9ncmFtMRYwFAYDVQQDDA0qLmxvY2FsZG9tYWluMSswKQYJKoZIhvcN +AQkBFhxzY29vcGhlYWx0aEBnb29nbGVncm91cHMuY29tMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDRCgGwrKMHmjc29QJ96z05Rf/JcqQM+s0XiDC+nQa6rjv0 +dXx2K7NanUAjn/K2N5hVPhQpaEhSCE4hfjXqrFcxgBcEW09hyMAoljHqS747pi8Q +j0n1GYs/soYF4zZzS7uJvmMw5RSQpjA1fptENFYihcj8zyDRlSNMbTxUyl9X6QID +AQABo1AwTjAdBgNVHQ4EFgQUltQ6g39ZWulvvY/kTFqqQnJGXY0wHwYDVR0jBBgw +FoAUltQ6g39ZWulvvY/kTFqqQnJGXY0wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B +AQUFAAOBgQB6V+HzYlW9qgu/xliFIu1EjJmLGOtBf4aRkdg6gSaxDB84SggoKKG0 +YzrTuYN9vv70zqGTDc76FKQSjuSugnmn6eCKkTi9/9Xvc0ZMdT3Hr3KQfgseTEpA +URHghVEJCn1s1OmW8Eb/I99FbhN6L8sibl9eWBSUZffTKiIJY3JX0g== +-----END CERTIFICATE----- diff --git a/cert/old_notes/README.cert b/cert/old_notes/README.cert new file mode 100644 index 0000000..d746a73 --- /dev/null +++ b/cert/old_notes/README.cert @@ -0,0 +1,16 @@ +mkdir ca +# Generate 4096-bit long RSA key for our root CA +openssl genrsa -out ca/LeadLab_root_cert_TEST.pem 4096 +# Create a self-signed root CA certificate +openssl req -new -x509 -days 1826 -key ca/LeadLab_root_cert_TEST.pem -out ca/LeadLab_root_cert_TEST.crt +# Create a subordinate CA used for actual signing +openssl genrsa -out endpoint.key 4096 +# Request a certificate for this subordinate CA +openssl req -new -key endpoint.key -out endpoint.csr +# Process request for the subordinate CA and get it signed by the root CA +openssl x509 -req -days 730 -in endpoint.csr -CA ca/LeadLab_root_cert_TEST.crt -CAkey ca/LeadLab_root_cert_TEST.pem -set_serial 5342365815382548354816354178354175 -out endpoint.crt +# Make client credentials +#openssl genrsa -out client.key 4096 +#openssl req -new -key client.key -out client.csr +#openssl x509 -req -days 730 -in client.csr -CA ca/LeadLab_root_cert_TEST.crt -CAkey ca/LeadLab_root_cert_TEST.pem -set_serial 5342365815382548354816354178354177 -out client.crt + diff --git a/cert/old_notes/endpoint-cert b/cert/old_notes/endpoint-cert new file mode 100755 index 0000000..00f9f15 --- /dev/null +++ b/cert/old_notes/endpoint-cert @@ -0,0 +1,7 @@ +rm ./endpoint.crt +rm ./endpoint.csr +rm ./endpoint.key +openssl genrsa -out endpoint.key 4096 +openssl req -new -key endpoint.key -out endpoint.csr +openssl x509 -req -days 300 -in endpoint.csr -CA ca/LeadLab_root_cert_TEST.pem -CAkey ca/LeadLab_root_cert_TEST.key -set_serial 4167245126451912541925481541687546 -out endpoint.crt + diff --git a/config/environments/development.rb b/config/environments/development.rb index 2c7c6f2..15b00cd 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -9,6 +9,8 @@ # Log error messages when you accidentally call methods on nil. config.whiny_nils = true + config.log_level = :info #:debug + # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false diff --git a/config/mongoid.yml b/config/mongoid.yml index 23b4d0d..495e56c 100644 --- a/config/mongoid.yml +++ b/config/mongoid.yml @@ -1,20 +1,87 @@ +production: + sessions: + default: + database: query_gateway_production + hosts: + - localhost:27017 + development: - host: localhost - database: query_gateway_development + # Configure available database sessions. (required) + sessions: + # Defines the default session. (required) + default: + # Defines the name of the default database that Mongoid can connect to. + # (required). + database: query_gateway_development + # Provides the hosts the default session can connect to. Must be an array + # of host:port pairs. (required) + hosts: + - localhost:27017 + options: + # Change whether the session persists in safe mode by default. + # (default: false) + # safe: false -test: - host: <%= ENV['TEST_DB_HOST'] || 'localhost' %> - database: query_gateway_test + # Change the default consistency model to :eventual or :strong. + # :eventual will send reads to secondaries, :strong sends everything + # to master. (default: :eventual) + # consistency: :eventual -# set these environment variables on your prod server -production: - host: <%= ENV['MONGOID_HOST'] %> - port: <%= ENV['MONGOID_PORT'] %> - username: <%= ENV['MONGOID_USERNAME'] %> - password: <%= ENV['MONGOID_PASSWORD'] %> - database: <%= ENV['MONGOID_DATABASE'] %> - # slaves: - # - host: slave1.local - # port: 27018 - # - host: slave2.local - # port: 27019 + # How many times Moped should attempt to retry an operation after + # failure. (default: 30) + # max_retries: 30 + + # The time in seconds that Moped should wait before retrying an + # operation on failure. (default: 1) + # retry_interval: 1 + # Configure Mongoid specific options. (optional) + options: + # Configuration for whether or not to allow access to fields that do + # not have a field definition on the model. (default: true) + # allow_dynamic_fields: true + + # Enable the identity map, needed for eager loading. (default: false) + # identity_map_enabled: false + + # Includes the root model name in json serialization. (default: false) + # include_root_in_json: false + + # Include the _type field in serializaion. (default: false) + # include_type_for_serialization: false + + # Preload all models in development, needed when models use + # inheritance. (default: false) + # preload_models: false + + # Protect id and type from mass assignment. (default: true) + # protect_sensitive_fields: true + + # Raise an error when performing a #find and the document is not found. + # (default: true) + # raise_not_found_error: true + + # Raise an error when defining a scope with the same name as an + # existing method. (default: false) + # scope_overwrite_exception: false + + # Skip the database version check, used when connecting to a db without + # admin access. (default: false) + # skip_version_check: false + + # User Active Support's time zone in conversions. (default: true) + # use_activesupport_time_zone: true + + # Ensure all times are UTC in the app side. (default: false) + # use_utc: false +test: + sessions: + default: + database: query_gateway_test + hosts: + - localhost:27017 + options: + consistency: :strong + # In the test environment we lower the retries and retry interval to + # low amounts for fast failures. + max_retries: 1 + retry_interval: 0 diff --git a/config/mongoid.yml.old b/config/mongoid.yml.old new file mode 100644 index 0000000..be2631f --- /dev/null +++ b/config/mongoid.yml.old @@ -0,0 +1,22 @@ +# Old config for Mongoid 2.x +development: + host: localhost + database: query_gateway_development + +test: + host: <%= ENV['TEST_DB_HOST'] || 'localhost' %> + database: query_gateway_test + +# set these environment variables on your prod server +production: + uri: <%= ENV['MONGOHQ_URL'] %> + #host: <%= ENV['MONGOID_HOST'] %> + #port: <%= ENV['MONGOID_PORT'] %> + #username: <%= ENV['MONGOID_USERNAME'] %> + #password: <%= ENV['MONGOID_PASSWORD'] %> + #database: <%= ENV['MONGOID_DATABASE'] %> + # slaves: + # - host: slave1.local + # port: 27018 + # - host: slave2.local + # port: 27019 diff --git a/config/routes.rb b/config/routes.rb index 887aac1..821c6d0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,25 +1,36 @@ QueryGateway::Application.routes.draw do + get 'sysinfo/load', :constraints => {:ip => /127.0.0.1/} + get 'sysinfo/users', :constraints => {:ip => /127.0.0.1/} + get 'sysinfo/diskspace', :constraints => {:ip => /127.0.0.1/} + get 'sysinfo/mongo', :constraints => {:ip => /127.0.0.1/} + get 'sysinfo/processes', :constraints => {:ip => /127.0.0.1/} + get 'sysinfo/swap', :constraints => {:ip => /127.0.0.1/} + get 'sysinfo/import', :constraints => {:ip => /127.0.0.1/} + get 'sysinfo/tomcat', :constraints => {:ip => /127.0.0.1/} + resources :results, :only => [:index, :show] resources :queries - post 'queries/upload_hqmf' + post 'queries/upload_hqmf', :constraints => {:ip => /127.0.0.1/} - post 'pmn/create' # not sure why this required given the following line but tests break without it - post 'pmn/PostRequest/:pmn_request_id', :to => 'pmn#create' - post 'pmn/PostRequestDocument/:id/:doc_id/:offset', :to => 'pmn#add' - put 'pmn/Start/:id', :to => 'pmn#start' - post 'pmn/Stop/:id', :to => 'pmn#stop' - get 'pmn/GetStatus/:id', :to => 'pmn#status' - get 'pmn/GetResponse/:id', :to => 'pmn#get_response' - get 'pmn/GetResponseDocument/:id/:doc_id/:offset', :to => 'pmn#doc' - get 'pmn/Close/:id', :to => 'pmn#close' + post 'pmn/create', :constraints => {:ip => /127.0.0.1/} # not sure why this required given the following line but tests break without it + post 'pmn/PostRequest/:pmn_request_id', :to => 'pmn#create', :constraints => {:ip => /127.0.0.1/} + post 'pmn/PostRequestDocument/:id/:doc_id/:offset', :to => 'pmn#add', :constraints => {:ip => /127.0.0.1/} + put 'pmn/Start/:id', :to => 'pmn#start', :constraints => {:ip => /127.0.0.1/} + post 'pmn/Stop/:id', :to => 'pmn#stop', :constraints => {:ip => /127.0.0.1/} + get 'pmn/GetStatus/:id', :to => 'pmn#status', :constraints => {:ip => /127.0.0.1/} + get 'pmn/GetResponse/:id', :to => 'pmn#get_response', :constraints => {:ip => /127.0.0.1/} + get 'pmn/GetResponseDocument/:id/:doc_id/:offset', :to => 'pmn#doc', :constraints => {:ip => /127.0.0.1/} + get 'pmn/Close/:id', :to => 'pmn#close', :constraints => {:ip => /127.0.0.1/} - get 'hdata/index' - get 'hdata/root' + get 'hdata/index', :constraints => {:ip => /127.0.0.1/} + get 'hdata/root', :constraints => {:ip => /127.0.0.1/} - post 'records/create' - post 'library_functions', :to => "library_functions#create" + post 'records/create', :constraints => {:ip => /127.0.0.1/} + delete 'records/destroy', :constraints => {:ip => /127.0.0.1/} + + post 'library_functions', :to => "library_functions#create", :constraints => {:ip => /127.0.0.1/} root :to => 'queries#index' diff --git a/db/seeds.rb b/db/seeds.rb index 95e724c..1b592d2 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -5,4 +5,7 @@ # # cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }]) # Mayor.create(name: 'Emanuel', city: cities.first) -`mongoimport -d #{Mongoid.master.name} -h #{Mongoid.master.connection.host_to_try[0]} --drop -c records test/fixtures/records.json` \ No newline at end of file +#`mongoimport -d #{Mongoid.master.name} -h #{Mongoid.master.connection.host_to_try[0]} --drop -c records test/fixtures/records.json` + +#puts "#{Mongoid.default_session.inspect}" +`mongoimport -d #{Mongoid.default_session.options[:database]} --drop --collection records --file test/fixtures/records.json` \ No newline at end of file diff --git a/doc_arch/endpoint_controllers.png b/doc_arch/endpoint_controllers.png new file mode 100644 index 0000000..2d1886c Binary files /dev/null and b/doc_arch/endpoint_controllers.png differ diff --git a/doc_arch/endpoint_full_models.dot b/doc_arch/endpoint_full_models.dot new file mode 100644 index 0000000..e4d55ee --- /dev/null +++ b/doc_arch/endpoint_full_models.dot @@ -0,0 +1,9 @@ +digraph models_diagram { + graph[overlap=false, splines=true] + "Query" [shape=Mrecord, label="{Query|_id :Moped::BSON::ObjectId\l_type :String\lcreated_at :Time\ldelayed_job_id :Object\lerror_message :String\lfilter :Hash\lformat :String\lfunctions :String\lmap :String\lreduce :String\lrequest_id :Object\lstatus :Symbol\lupdated_at :Time\l}"] + "Result" [shape=Mrecord, label="{Result|_id :Moped::BSON::ObjectId\l_type :String\lcreated_at :Time\lquery_id :Object\l}"] + "JobLog" [shape=Mrecord, label="{JobLog|_id :Moped::BSON::ObjectId\l_type :String\lcreated_at :Time\lmessage :String\l}"] + "Query" -> "JobLog" [arrowtail=odot, arrowhead=crow, dir=both color="#44E053"] + "Query" -> "Result" [arrowtail=odot, arrowhead=dot, dir=both color="#4C7944"] + "JobLog" -> "Query" [arrowtail=crow, arrowhead=crow, dir=both color="#4657DB"] +} diff --git a/doc_arch/endpoint_full_models.png b/doc_arch/endpoint_full_models.png new file mode 100644 index 0000000..390f876 Binary files /dev/null and b/doc_arch/endpoint_full_models.png differ diff --git a/lib/job_stats.rb b/lib/job_stats.rb index 52dcdea..bd8ad82 100644 --- a/lib/job_stats.rb +++ b/lib/job_stats.rb @@ -30,12 +30,14 @@ class JobStats def self.stats # check to see if we have a working connection to mongo begin - Mongoid.master.stats + #Mongoid.master.stats + Mongoid.default_session.stats rescue return {error: "Backend Down"} end s = {backend_status: :good} + #result = Query.collection().map_reduce(MAP, REDUCE, {out: {inline: 1}, raw: true}) result = Query.collection().map_reduce(MAP, REDUCE, {out: {inline: 1}, raw: true}) result["results"].each do |res| type = res["_id"] diff --git a/lib/mongo_query_executor.rb b/lib/mongo_query_executor.rb index 1f83bba..069c3fc 100644 --- a/lib/mongo_query_executor.rb +++ b/lib/mongo_query_executor.rb @@ -18,10 +18,24 @@ def initialize(format, map_js, reduce_js, functions_js, query_id, filter={}) end def execute - db = Mongoid.master + #db = Mongoid.master + db = Mongoid.default_session #.options[:database] exts = [] exts << @functions_js - results = db[PATIENTS_COLLECTION].map_reduce(build_map_function(exts), build_reduce_function(), :query => @filter, raw: true, out: {inline: 1}) + #results = db[PATIENTS_COLLECTION].map_reduce(build_map_function(exts), build_reduce_function(), :query => @filter, raw: true, out: {inline: 1}) + + # An example of using Moped to execute a map_reduce command on a session + # can be found at http://mongoid.org/en/moped/docs/driver.html under + # Session#command + results = db.command( + mapreduce: PATIENTS_COLLECTION, + map: build_map_function(exts), + reduce: @reduce_js, + query: @filter, + raw: true, + out: {inline: 1} + ) + result = {} results['results'].each do |rv| key = QueryUtilities.stringify_key(rv['_id']) @@ -49,25 +63,4 @@ def build_map_function(exts = "") map(patient); };" end - - def build_reduce_function() - "function(k,v){ - - var iter = function(x){ - this.index = 0; - this.arr = (x==null)? [] : x; - - this.hasNext = function(){ - return this.index < this.arr.length; - }; - - this.next = function(){ - return this.arr[this.index++]; - } - }; - - #{@reduce_js} - return reduce(k,new iter(v)); - }" - end end diff --git a/lib/patient_console.rb b/lib/patient_console.rb index d1bf882..be9a841 100644 --- a/lib/patient_console.rb +++ b/lib/patient_console.rb @@ -48,7 +48,8 @@ def self.run next end query = JSON.parse(parts[1..parts.length].join(' ')) - db = Mongoid.master + #db = Mongoid.master + db = Mongoid.default_session @@patients = [] @@ -81,7 +82,8 @@ def self.load_patient(index) def self.init @@patient_index = 0 - db = Mongoid.master + #db = Mongoid.master + db = Mongoid.default_session patient_api = QueryExecutor.patient_api_javascript.to_s @@patients = [] db['records'].find().each {|p| @@patients << p} diff --git a/lib/query_job.rb b/lib/query_job.rb index 6437656..afddc80 100644 --- a/lib/query_job.rb +++ b/lib/query_job.rb @@ -1,4 +1,4 @@ -require 'mongo' +#require 'mongo' class QueryJob < Struct.new(:format, :map, :reduce,:functions, :filter, :query_id) @@ -47,7 +47,9 @@ def self.submit(format, map, reduce, functions, filter = {}, query_id) end def self.find_job(job_id) - Delayed::Job.find(BSON::ObjectId.from_string(job_id)) + #TODO test this, method doesn't seem to be used anywhere + #Delayed::Job.find(Moped::BSON::ObjectId.from_string(job_id)) + Delayed::Job.find(Moped::BSON::ObjectId(job_id)) end def self.cancel_job(job_id) diff --git a/lib/query_utilities.rb b/lib/query_utilities.rb index 20b71a6..c579282 100644 --- a/lib/query_utilities.rb +++ b/lib/query_utilities.rb @@ -4,7 +4,7 @@ module QueryUtilities require 'tilt' def self.stringify_key(key) - if (key.is_a? BSON::OrderedHash) + if (key.is_a? Moped::BSON::Document) #::OrderedHash) key = (key.map {|val| stringify_key(val)}).join('_') end if (key.is_a? Array) diff --git a/lib/tasks/.gitkeep b/lib/tasks/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/lib/tasks/patient_console.rake b/lib/tasks/patient_console.rake index 3659cb2..ae92db5 100644 --- a/lib/tasks/patient_console.rake +++ b/lib/tasks/patient_console.rake @@ -1,6 +1,6 @@ require 'patient_console' require 'bundler/setup' -require 'test/unit' +require 'test/unit/testcase' require 'tilt' require 'coffee_script' require 'sprockets' @@ -14,4 +14,4 @@ namespace :patient do PatientConsole.run end -end \ No newline at end of file +end diff --git a/nagios-plugins/README.md b/nagios-plugins/README.md new file mode 100644 index 0000000..86ccdbb --- /dev/null +++ b/nagios-plugins/README.md @@ -0,0 +1 @@ +The Nagios plugins (check_disk, check_load, check_procs, check_swap, check_users) in this directory were extracted from the Ubuntu 14.04 LTS package nagios-plugins-basic, version 1.5-3ubuntu1. diff --git a/nagios-plugins/check_disk b/nagios-plugins/check_disk new file mode 100755 index 0000000..c9dcddb Binary files /dev/null and b/nagios-plugins/check_disk differ diff --git a/nagios-plugins/check_import.sh b/nagios-plugins/check_import.sh new file mode 100755 index 0000000..769f09e --- /dev/null +++ b/nagios-plugins/check_import.sh @@ -0,0 +1,44 @@ +#!/bin/sh +# Check current and previous tomcat6 log for pattern 'records pending' and +# 'records processed'. If we check logs for the previous day there should +# be at least 2 pattern matches +LOGFILE=/var/log/tomcat6/catalina.out +LOGFILE1=/var/log/tomcat6/catalina.out.1.gz +DATE=`/bin/date --date='yesterday' +"%Y-%m-%d"` +TMPFILE=`/bin/tempfile` +CMD=`grep "records p" $LOGFILE > $TMPFILE 2>&1` +STATUS=$? +if [ $STATUS -ge 2 ]; then + /bin/echo "UNKNOWN - Got $(/bin/cat $TMPFILE)" + /bin/rm $TMPFILE + exit 3 +fi +CMD1=`zcat $LOGFILE1 | grep "records p" - >> $TMPFILE 2>&1` +STATUS1=$? +if [ $STATUS1 -ge 2 ]; then + /bin/echo "UNKNOWN - Got $(/bin/cat $TMPFILE)" + /bin/rm $TMPFILE + exit 3 +fi +COUNT=`grep "$DATE" $TMPFILE | wc -l` +if [ $COUNT -ge 2 ]; then + COUNTP=`grep "$DATE" $TMPFILE | grep "records processed" | wc -l` + if [ $COUNTP -ge 1 ]; then + echo "OK - 'records processed' has $COUNTP matches on $DATE" + /bin/rm $TMPFILE + exit 0 + else + echo "WARNING - 'records processed' has 0 matches on $DATE" + /bin/rm $TMPFILE + exit 1 + fi +fi +if [ $COUNT -eq 1 ]; then + echo "WARNING - 'records p' has only 1 match on $DATE" + /bin/rm $TMPFILE + exit 1 +else + echo "CRITICAL - 'records p' has 0 matches on $DATE" + /bin/rm $TMPFILE + exit 2 +fi diff --git a/nagios-plugins/check_load b/nagios-plugins/check_load new file mode 100755 index 0000000..8e6966c Binary files /dev/null and b/nagios-plugins/check_load differ diff --git a/nagios-plugins/check_procs b/nagios-plugins/check_procs new file mode 100755 index 0000000..2807870 Binary files /dev/null and b/nagios-plugins/check_procs differ diff --git a/nagios-plugins/check_swap b/nagios-plugins/check_swap new file mode 100755 index 0000000..1c7dc19 Binary files /dev/null and b/nagios-plugins/check_swap differ diff --git a/nagios-plugins/check_users b/nagios-plugins/check_users new file mode 100755 index 0000000..02b3d8c Binary files /dev/null and b/nagios-plugins/check_users differ diff --git a/runme.bat b/runme.bat new file mode 100644 index 0000000..199d3b2 --- /dev/null +++ b/runme.bat @@ -0,0 +1,9 @@ +::Windows Normal Gateway Startup Script + +@echo off +echo "Installing Dependencies" +call bundle install +echo "Starting Delayed Job" +call "cmd /c start /min bundle exec ruby script/delayed_job run" +echo "Starting Normal Gateway" +bundle exec rails server -p 3001 diff --git a/runme.sh b/runme.sh new file mode 100755 index 0000000..b717da2 --- /dev/null +++ b/runme.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# Start Normal HTTP Gateway + +echo "Installing Dependencies" +bundle install +echo "Starting Delayed Job" +bundle exec script/delayed_job start +echo "Starting Normal Gateway" +bundle exec rails server -p 3001 +echo "Stopping Delayed Job" +bundle exec script/delayed_job stop diff --git a/script/rails b/script/rails index f8da2cf..7489a5a 100755 --- a/script/rails +++ b/script/rails @@ -1,6 +1,39 @@ #!/usr/bin/env ruby # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. -APP_PATH = File.expand_path('../../config/application', __FILE__) -require File.expand_path('../../config/boot', __FILE__) +require 'rubygems' +require 'rails/commands/server' +require 'rack' +require 'webrick' +require 'webrick/https' + +#override server defaults options to use ssl +CA_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +#SERVER_CERT_PATH = "cert/endpoint.crt" +#SERVER_KEY_PATH = "cert/endpoint.key" +SERVER_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +SERVER_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" + +module Rails + class Server < ::Rack::Server + def default_options + super.merge({ + :environment => (ENV['RAILS_ENV'] || "development").dup, + :daemonize => false, + :debugger => false, + :pid => File.expand_path("tmp/pids/server.pid"), + :config => File.expand_path("config.ru"), + :SSLEnable => false, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT, + :SSLPrivateKey => OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH).read), + :SSLCertificate => OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH).read), + :SSLCACertificateFile => CA_CERT_PATH, + :SSLCertName => [["CN", WEBrick::Utils::getservername]], + }) + end + end +end + +APP_PATH = File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' diff --git a/script/secure_rails b/script/secure_rails new file mode 100755 index 0000000..fe9e04b --- /dev/null +++ b/script/secure_rails @@ -0,0 +1,39 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. + +require 'rubygems' +require 'rails/commands/server' +require 'rack' +require 'webrick' +require 'webrick/https' + +#override server defaults options to use ssl +CA_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +#SERVER_CERT_PATH = "cert/endpoint.crt" +#SERVER_KEY_PATH = "cert/endpoint.key" +SERVER_CERT_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" +SERVER_KEY_PATH = "cert/ca/LeadLab_root_cert_TEST.pem" + +module Rails + class Server < ::Rack::Server + def default_options + super.merge({ + :environment => (ENV['RAILS_ENV'] || "development").dup, + :daemonize => false, + :debugger => false, + :pid => File.expand_path("tmp/pids/secure_server.pid"), + :config => File.expand_path("config.ru"), + :SSLEnable => true, + :SSLVerifyClient => OpenSSL::SSL::VERIFY_PEER|OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT, + :SSLPrivateKey => OpenSSL::PKey::RSA.new(File.open(SERVER_KEY_PATH).read), + :SSLCertificate => OpenSSL::X509::Certificate.new(File.open(SERVER_CERT_PATH).read), + :SSLCACertificateFile => CA_CERT_PATH, + :SSLCertName => [["CN", WEBrick::Utils::getservername]], + }) + end + end +end + +APP_PATH = File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) +require 'rails/commands' diff --git a/secrunme.sh b/secrunme.sh new file mode 100755 index 0000000..a73a20e --- /dev/null +++ b/secrunme.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# Start Secure HTTPS Gateway + +echo "Installing Dependencies" +bundle install +echo "Starting Delayed Job" +bundle exec script/delayed_job start +echo "Starting Secure Gateway" +bundle exec script/secure_rails server -p 3222 +echo "Stopping Delayed Job" +bundle exec script/delayed_job stop diff --git a/start-endpoint-example.sh b/start-endpoint-example.sh new file mode 100755 index 0000000..b909c5f --- /dev/null +++ b/start-endpoint-example.sh @@ -0,0 +1,44 @@ +#!/bin/bash +#export HOME=/home/scoopadmin +source $HOME/.bash_profile +source $HOME/.bashrc +export ENDPOINT=$HOME/git/scoophealth/hquery/query-gateway +export GW_PIDFILE=$ENDPOINT/tmp/pids/server.pid +export DL_PIDFILE=$ENDPOINT/tmp/pids/delayed_job.pid +# +# Make sure mongod is running +if ! pgrep mongod > /dev/null +then + sudo service mongod start +fi +# +#echo "Starting relay service on port 3000" +#$ENDPOINT/util/relay-service.rb >> $HOME/logs/rs.log 2>&1 & +# +echo "Starting Query Gateway on port 3001" +cd $ENDPOINT +# Stop delayed_job if running, remove pidfile +if [ -f $DL_PIDFILE ]; +then + bundle exec $ENDPOINT/script/delayed_job stop + if [ -f $DL_PIDFILE ]; + then + rm $DL_PIDFILE + fi +fi +# +bundle exec $ENDPOINT/script/delayed_job start +# +# Start gateway +# If gateway is already running (or has a stale server.pid), try to stop it. +if [ -f $GW_PIDFILE ]; +then + kill `cat $GW_PIDFILE` + if [ -f $GW_PIDFILE ]; + then + kill -9 `cat $GW_PIDFILE` + fi + rm $GW_PIDFILE +fi +bundle exec rails server -p 3001 >> $ENDPOINT/log/qgw.log 2>&1 & +#/bin/ps -ef | grep "rails server -p 3001" | grep -v grep | awk '{print $2}' > tmp/pids/server.pid diff --git a/stop-endpoint-example.sh b/stop-endpoint-example.sh new file mode 100755 index 0000000..ca094b6 --- /dev/null +++ b/stop-endpoint-example.sh @@ -0,0 +1,27 @@ +#!/bin/bash +source $HOME/.bash_profile +source $HOME/.bashrc +export ENDPOINT=$HOME/git/scoophealth/hquery/query-gateway +export GW_PIDFILE=$ENDPOINT/tmp/pids/server.pid +export DL_PIDFILE=$ENDPOINT/tmp/pids/delayed_job.pid +cd $ENDPOINT +if [ -f $DL_PIDFILE ]; +then + bundle exec $ENDPOINT/script/delayed_job stop + # pid file should be gone but recheck + if [ -f $DL_PIDFILE ]; + then + rm $DL_PIDFILE + fi +fi +# +# If gateway is running, stop it. +if [ -f $GW_PIDFILE ]; +then + kill `cat $GW_PIDFILE` + if [ -f $GW_PIDFILE ]; + then + kill -9 `cat $GW_PIDFILE` + fi + rm $GW_PIDFILE +fi diff --git a/support/oscar/interface_check.sh b/support/oscar/interface_check.sh new file mode 100755 index 0000000..74ee8c4 --- /dev/null +++ b/support/oscar/interface_check.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# Bring up static interface if it is down; fails silently if that +# IP address is already assigned to another interface, say via DHCP. +# Example of usage via cron: +#@midnight /root/bin/interface_check.sh > /dev/null 2>&1 + +IPADDRESS=192.168.0.13 # change to actual private IP address +t1=$(ifconfig | grep -o em1:1) +t2='em1:1' + +if [ "$t1" != "$t2" ]; then + /sbin/ifconfig em1:1 $IPADDRESS netmask 255.255.255.0 +fi + +exit diff --git a/support/oscar/mysql_reload.sh b/support/oscar/mysql_reload.sh new file mode 100755 index 0000000..d5aba10 --- /dev/null +++ b/support/oscar/mysql_reload.sh @@ -0,0 +1,35 @@ +#!/bin/bash +set -e # exit on errors +# Example usage from cron: +# 15 8 * * * /encrypted/root/mysql_reload.sh >> /encrypted/root/log/reload.log 2>&1 +# +# Stop Tomcat. Nagios test of whether load succeeded +# checks whether this script restarted Tomcat. +# That will happen if script runs to completion. +# In any case, Oscar cannot run while the database +# is being restored from a dump. +echo "Stopping Tomcat at `date`" +/etc/init.d/tomcat6 stop +# +echo "Datebase dump inspection started at `date`" +DUMPFILE="/encrypted/somedir/somedump.sql" +CMD=`find $DUMPFILE -mtime 0 -print | wc -l` +if [ $CMD -eq 0 ] +then + HOST=`/bin/hostname` + echo "Check why the EMR SQL dump on $HOST failed to update for `date`." + exit +fi +echo "Database dump appears current" +echo "Database reloading started at `date`" +DBNAME="oscar_12_1" +PASSWD="somepasswd" +# +mysql -uroot -p$PASSWD -e "drop database $DBNAME;" +mysql -uroot -p$PASSWD -e "create database $DBNAME;" +mysql -uroot -p$PASSWD $DBNAME < $DUMPFILE +# +echo "Completed database reload at `date`" +# restart Oscar +/etc/init.d/tomcat6 start +echo "Tomcat restart completed at `date`" diff --git a/test/factories/factory.rb b/test/factories/factory.rb index a85b733..ad46bc4 100644 --- a/test/factories/factory.rb +++ b/test/factories/factory.rb @@ -4,57 +4,69 @@ # = jobs = # ========== -Factory.define :queued_job, :class => Query do |q| - q.format 'js' - q.map 'foo' - q.reduce 'foo' - q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued')] - q.status :queued +FactoryGirl.define do + factory :queued_job, :class => Query do |q| + q.format 'js' + q.map 'foo' + q.reduce 'foo' + q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued')] + q.status :queued + end end -Factory.define :running_job, :class => Query do |q| - q.format 'js' - q.map 'foo' - q.reduce 'foo' - q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued'), - JobLog.new(:created_at => 45.seconds.ago.time, :message => 'Job running')] - q.status :running +FactoryGirl.define do + factory :running_job, :class => Query do |q| + q.format 'js' + q.map 'foo' + q.reduce 'foo' + q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued'), + JobLog.new(:created_at => 45.seconds.ago.time, :message => 'Job running')] + q.status :running + end end -Factory.define :successful_job, :class => Query do |q| - q.format 'js' - q.map 'foo' - q.reduce 'foo' - q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued'), - JobLog.new(:created_at => 45.seconds.ago.time, :message => 'Job running'), - JobLog.new(:created_at => 30.seconds.ago.time, :message => 'Job successful')] - q.status :complete +FactoryGirl.define do + factory :successful_job, :class => Query do |q| + q.format 'js' + q.map 'foo' + q.reduce 'foo' + q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued'), + JobLog.new(:created_at => 45.seconds.ago.time, :message => 'Job running'), + JobLog.new(:created_at => 30.seconds.ago.time, :message => 'Job successful')] + q.status :complete + end end -Factory.define :rescheduled_job,:class => Query do |q| - q.format 'js' - q.map 'foo' - q.reduce 'foo' - q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued'), - JobLog.new(:created_at => 45.seconds.ago.time, :message => 'Job running'), - JobLog.new(:created_at => 15.seconds.ago.time, :message => 'Job rescheduled')] - q.status :rescheduled +FactoryGirl.define do + factory :rescheduled_job,:class => Query do |q| + q.format 'js' + q.map 'foo' + q.reduce 'foo' + q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued'), + JobLog.new(:created_at => 45.seconds.ago.time, :message => 'Job running'), + JobLog.new(:created_at => 15.seconds.ago.time, :message => 'Job rescheduled')] + q.status :rescheduled + end end -Factory.define :failed_job, :class => Query do |q| - q.format 'js' - q.map 'foo' - q.reduce 'foo' - q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued'), - JobLog.new(:created_at => 45.seconds.ago.time, :message => 'Job running'), - JobLog.new(:created_at => 10.seconds.ago.time, :message => 'Job failed')] - q.status :failed +FactoryGirl.define do + factory :failed_job, :class => Query do |q| + q.format 'js' + q.map 'foo' + q.reduce 'foo' + q.job_logs [JobLog.new(:created_at => 60.seconds.ago.time, :message => 'Job queued'), + JobLog.new(:created_at => 45.seconds.ago.time, :message => 'Job running'), + JobLog.new(:created_at => 10.seconds.ago.time, :message => 'Job failed')] + q.status :failed + end end # =========== # = Results = # =========== -Factory.define :gender_result, :class => Result do |r| - r.created_at Time.now -end \ No newline at end of file +FactoryGirl.define do + factory :gender_result, :class => Result do |r| + r.created_at Time.now + end +end diff --git a/test/fixtures/.gitkeep b/test/fixtures/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/fixtures/JOHN_CLEESE_1_25091940.xml b/test/fixtures/JOHN_CLEESE_1_25091940.xml new file mode 100644 index 0000000..6ff7089 --- /dev/null +++ b/test/fixtures/JOHN_CLEESE_1_25091940.xml @@ -0,0 +1,4268 @@ + + + + + + + + + + + + + + + PITO EMR-2-EMR Record of JOHN CLEESE + + + + + + + + + + BC + + + + + JOHN + CLEESE + + + + + + + + + + + + + + + + + + + + McMaster Hospital + + + + + + + + + + + + + + +
+ + + Advance Directives Section [without entries] + This section is not supported by the Originating Application + + + + + + + + + +
+
+ + +
+ + + Alerts [with entries] + + + Heart Attack + + + + + + + + + Heart Attack + + + + + + + +
+
+ + +
+ + + Allergies & Intolerances (Reaction List) [with entries] + + + PENICILLINS, COMBINATIONS WITH OTHER ANTIBACTERIAL + + + + + + + + + + + + + + + + + + + + + + + PENICILLINS, COMBINATIONS WITH OTHER ANTIBACTERIAL + + + + + + + + + + + + + + + + + + + + + + + + Confirmed present + + + + + + + +
+
+ + +
+ + + Clinical Measured Observations [with entries] + + + Systolic Blood Pressure: 130 mm[Hg] (sitting position) + Diastolic Blood Pressure: 85 mm[Hg] (sitting position) + Height: 187 cm (in cm) + Heart Rate: 85 beats/min (in bpm (nnn) Range:40-180) + Temperature: 37 C (degrees celcius) + Waist: 92 cm (Waist Circum in cm) + Weight: 95 kg (in kg) + + + + + + + + + + + + + + + + + + + Systolic Blood Pressure (sitting position) + + + + + + + + + + + + + + + + + + + + + + + + + Diastolic Blood Pressure (sitting position) + + + + + + + + + + + + + + + + + + + + + + + + + Height (in cm) + + + + + + + + + + + + + + + + + + + + + + + + + Heart Rate (in bpm (nnn) Range:40-180) + + + + + + + + + + + + + + + + + + + + + + + + + Temperature (degrees celcius) + + + + + + + + + + + + + + + + + + + + + + + + + Waist (Waist Circum in cm) + + + + + + + + + + + + + + + + + + + + + + + + + Weight (in kg) + + + + + + + + +
+
+ + +
+ + + Encounter History and Notes [with entries] + + + Sep 25, 2013 [25-Sep-2013 .: Tel-Progress Notes] +BP 130/85 sitting position +HT 187 in cm +HR 85 in bpm (nnn) Range:40-180 +TEMP 37 degrees celcius +WAIS 92 Waist Circum in cm +WT 95 in kg + Sep 26, 2013 Situational Crisis + Sep 26, 2013 Vitamin D3 + Sep 26, 2013 Vitamin C + Sep 26, 2013 Ginseng Tincture + Sep 26, 2013 Heart Attack + + + + + + + + + + + + + + + + + + + + + + + + + + doctor + oscardoc + + Provider + + + + + + + + + + + + [25-Sep-2013 .: Tel-Progress Notes] +BP 130/85 sitting position +HT 187 in cm +HR 85 in bpm (nnn) Range:40-180 +TEMP 37 degrees celcius +WAIS 92 Waist Circum in cm +WT 95 in kg + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + doctor + oscardoc + + Provider + + + + + + + + + + + + Situational Crisis + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + doctor + oscardoc + + Provider + + + + + + + + + + + + Vitamin D3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + doctor + oscardoc + + Provider + + + + + + + + + + + + Vitamin C + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + doctor + oscardoc + + Provider + + + + + + + + + + + + Ginseng Tincture + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + doctor + oscardoc + + Provider + + + + + + + + + + + + Heart Attack + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + + Family History [without entries] + No information for this section for this patient + + + + + + + + + + + + + + +
+
+ + +
+ + + Immunizations List [with entries] + + + Td Sep 01, 2012 Completed + Flu Feb 01, 2009 Completed + Pneumovax Oct 31, 2012 Completed + + + + + + + + + + + + + + IM + + + + + + + Td + 1234 + + + + + + + + + + + + + + + Left Delt + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Flu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IM + + + + + + + Pneumovax + + + + + + + + + + + + + + + Right Delt + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + + Laboratory Results and Reports [with entries] + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + WBC: 8.0 giga/L + RBC: 4.71 tera/L + Hemoglobin: 158 g/L + Hematocrit: 0.46 + MCV: 99 fl + MCH: 33.5 pg + MCHC: 341 g/L + RDW: 12.6 % + Platelet Count: 295 giga/L + Neutrophils: 6.0 giga/L + Lymphocytes: 1.6 giga/L + Monocytes: 0.4 giga/L + Eosinophils: 0.1 giga/L + Basophils: 0.0 giga/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + INR: 1.0 + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + Glucose Random: 5.2 mmol/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + Creatinine: 68 umol/L + Estimated GFR: 113 mL/min + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + Uric Acid: 317 umol/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + Albumin: 45 g/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + Total Bilirubin: 16 umol/L + Direct Bilirubin: 5 umol/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + Alkaline Phosphatase: 74 U/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + Gamma GT: 10 U/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + ALT: 19 U/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + AST: 25 U/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + Lactic Acid: 1.0 mmol/L + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 Jun 27, 2013 + Lipemia: Slight + + + + + + + + + HAEM1/HAEM3/CHEM4/CHEM29/REFER1 + + + + + + + + + + + + + + + + + + + + WBC + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 4.0 + + + + + + + + + + + + + + RBC + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 4.20 + + + + + + + + + + + + + + Hemoglobin + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 133 + + + + + + + + + + + + + + Hematocrit + + + + + 0.46 + + + + + + + + + + + + + + + + + Normal Reference range is greater than 0.38 + + + + + + + + + + + + + + MCV + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 82 + + + + + + + + + + + + + + MCH + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 27.5 + + + + + + + + + + + + + + MCHC + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 305 + + + + + + + + + + + + + + RDW + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 11.5 + + + + + + + + + + + + + + Platelet Count + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 150 + + + + + + + + + + + + + + Neutrophils + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 2.0 + + + + + + + + + + + + + + Lymphocytes + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 1.0 + + + + + + + + + + + + + + Monocytes + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 0.1 + + + + + + + + + + + + + + Eosinophils + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 0.0 + + + + + + + + + + + + + + Basophils + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 0.0 + + + + + + + + + + + + + + + + + + + + + + + + INR + + + + + 1.0 + + + + + + + + + + + + + + + + + Normal Reference range is greater than 0.8 + + + + + + + + + + + + + + + + + + + + + + + + Glucose Random + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 3.3 + + + + + + + + + + + + + + + + + + + + + + + + Creatinine + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 70 + + + + + + + + + + + + + + Estimated GFR + + + + + + + + + + + + + + + + + + + + + + >=60 + >=60 + + + + + + + + + + + + + + + + + + + + + Uric Acid + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 234 + + + + + + + + + + + + + + + + + + + + + + + + Albumin + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 35 + + + + + + + + + + + + + + + + + + + + + + + + Total Bilirubin + + + + + + + + + + + + + + + + + + + + + + + + + + + Direct Bilirubin + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Alkaline Phosphatase + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 48 + + + + + + + + + + + + + + + + + + + + + + + + Gamma GT + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 10 + + + + + + + + + + + + + + + + + + + + + + + + ALT + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AST + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lactic Acid + + + + + + + + + + + + + + + + + + + + + + Normal Reference range is greater than 0.7 + + + + + + + + + + + + + + + + + + + + + + + + Lipemia + + + + + Slight + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + + Medications and Prescriptions - Medication List [with entries] + + + TYLENOL EXTRA STRENGTH TAB 500MG QID 25 D + SPIRONOLACTONE 25MG TABLET QAM 28 D + IBUPROFEN TAB 400MG TID 28 D + ATIVAN 1MG BID 20 D + ASA 81 MG OD 28 D + FUROSEMIDE 20MG QAM 56 D + AVA-RAMIPRIL 5MG OD 28 D + CARVEDILOL 12.5MG OD 28 D + ATORVASTATIN 40MG OD 28 D + + + + + + + + + + + + + + + + + ACETAMINOPHEN + TYLENOL EXTRA STRENGTH TAB 500MG + + + + + + ACETAMINOPHEN + + + + + + + + + + + + Long Term + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ACETAMINOPHEN + TYLENOL EXTRA STRENGTH TAB 500MG + + + + + + ACETAMINOPHEN + + + + + + + + + + + + + + + + 25 D + + + + + + + + + + + + + + + + + + + + + + + + + ACETAMINOPHEN + TYLENOL EXTRA STRENGTH TAB 500MG + + + + + + ACETAMINOPHEN + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SPIRONOLACTONE + SPIRONOLACTONE 25MG TABLET + + + + + + SPIRONOLACTONE + + + + + + + + + + + + Long Term + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SPIRONOLACTONE + SPIRONOLACTONE 25MG TABLET + + + + + + SPIRONOLACTONE + + + + + + + + + + + + + + + + 28 D + + + + + + + + + + + + + + + + + + + + + + + + + SPIRONOLACTONE + SPIRONOLACTONE 25MG TABLET + + + + + + SPIRONOLACTONE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IBUPROFEN + IBUPROFEN TAB 400MG + + + + + + IBUPROFEN + + + + + + + + + + + + Long Term + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IBUPROFEN + IBUPROFEN TAB 400MG + + + + + + IBUPROFEN + + + + + + + + + + + + + + + + 28 D + + + + + + + + + + + + + + + + + + + + + + + + + IBUPROFEN + IBUPROFEN TAB 400MG + + + + + + IBUPROFEN + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LORAZEPAM + ATIVAN 1MG + + + + + + LORAZEPAM + + + + + + + + + + + + Long Term + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + LORAZEPAM + ATIVAN 1MG + + + + + + LORAZEPAM + + + + + + + + + + + + + + + + 20 D + + + + + + + + + + + + + + + + + + + + + + + + + LORAZEPAM + ATIVAN 1MG + + + + + + LORAZEPAM + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ACETYLSALICYLIC ACID + ASA 81 MG + + + + + + ACETYLSALICYLIC ACID + + + + + + + + + + + + Long Term + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ACETYLSALICYLIC ACID + ASA 81 MG + + + + + + ACETYLSALICYLIC ACID + + + + + + + + + + + + + + + + 28 D + + + + + + + + + + + + + + + + + + + + + + + + + ACETYLSALICYLIC ACID + ASA 81 MG + + + + + + ACETYLSALICYLIC ACID + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FUROSEMIDE + FUROSEMIDE 20MG + + + + + + FUROSEMIDE + + + + + + + + + + + + Long Term + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + FUROSEMIDE + FUROSEMIDE 20MG + + + + + + FUROSEMIDE + + + + + + + + + + + + + + + + 56 D + + + + + + + + + + + + + + + + + + + + + + + + + FUROSEMIDE + FUROSEMIDE 20MG + + + + + + FUROSEMIDE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RAMIPRIL + AVA-RAMIPRIL 5MG + + + + + + RAMIPRIL + + + + + + + + + + + + Long Term + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + RAMIPRIL + AVA-RAMIPRIL 5MG + + + + + + RAMIPRIL + + + + + + + + + + + + + + + + 28 D + + + + + + + + + + + + + + + + + + + + + + + + + RAMIPRIL + AVA-RAMIPRIL 5MG + + + + + + RAMIPRIL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CARVEDILOL + CARVEDILOL 12.5MG + + + + + + CARVEDILOL + + + + + + + + + + + + Long Term + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CARVEDILOL + CARVEDILOL 12.5MG + + + + + + CARVEDILOL + + + + + + + + + + + + + + + + 28 D + + + + + + + + + + + + + + + + + + + + + + + + + CARVEDILOL + CARVEDILOL 12.5MG + + + + + + CARVEDILOL + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ATORVASTATIN (ATORVASTATIN CALCIUM) + ATORVASTATIN 40MG + + + + + + ATORVASTATIN (ATORVASTATIN CALCIUM) + + + + + + + + + + + + Long Term + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ATORVASTATIN (ATORVASTATIN CALCIUM) + ATORVASTATIN 40MG + + + + + + ATORVASTATIN (ATORVASTATIN CALCIUM) + + + + + + + + + + + + + + + + 28 D + + + + + + + + + + + + + + + + + + + + + + + + + ATORVASTATIN (ATORVASTATIN CALCIUM) + ATORVASTATIN 40MG + + + + + + ATORVASTATIN (ATORVASTATIN CALCIUM) + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + + Orders and Requests (without entries) + This section is not supported by the Originating Application + + + + + + + + + + + + + + + +
+
+ + +
+ + + Problems and Conditions - Problem List [with entries] + + + HEART FAILURE* (ICD9: 428) + ESSENTIAL HYPERTENSION* (ICD9: 401) + DIABETES MELLITUS* (ICD9: 250) + CHRONIC BRONCHITIS* (ICD9: 491) + + + + + + + + + HEART FAILURE* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ESSENTIAL HYPERTENSION* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DIABETES MELLITUS* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + CHRONIC BRONCHITIS* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+ + + Risk Factors [with entries] + + + Situational Crisis + + + + + + + + + + + + + + + + + + + + Situational Crisis + + + + + + + + +
+
+
+
+
diff --git a/test/fixtures/MZarilla.xml b/test/fixtures/MZarilla.xml new file mode 100644 index 0000000..7eca174 --- /dev/null +++ b/test/fixtures/MZarilla.xml @@ -0,0 +1,3457 @@ + + + + + + + + + + + A basic document + + + + + + + + 1022 Main Street + Vancouver + BC + V3J3L2 + Canada + + + + + Melvin + Zarilla + + + + + + + + + + + + + ABCDEF + + + + + + + +
+ + + Advance Directives Section [with entries] + This section is not supported by the Originating Application + + + + + + + + + +
+
+ +
+ + + Alerts [with entries] + Special Needs Support: Possible evidence of autism. +Demonstrates early symptoms of autism., Effective Date: Jan 15, 2013 +Other: Feeding Issues. +Discuss alternative feeding methods., Effective Date: Jun 08, 2011 +Other: Parents refusing immunization. +Discussion with parents prior to any injections., Effective Date: Jan 08, 2011 + + + + + + Special Needs Support + + + + + + + + + Possible evidence of autism. +Demonstrates early symptoms of autism. + + + + + + + + + + + Other + + + + + + + + + Parents refusing immunization. +Discussion with parents prior to any injections. + + + + + + + + + + + Other + + + + + + + + + Feeding Issues. +Discuss alternative feeding methods. + + + + + +
+
+ +
+ + + Allergies & Intolerances (Reaction List) [with entries] + Food Allergy: Lactose - dietary (substance), Severity: Severe, Details: Reported by Mother, Start: Jul 15, 2012 +Drug Allergy: Amoxicillin, Severity: Moderate, Details: Presented in clinic with hives, Start: May 08, 2012, End: May 08, 2012 +Food Allergy: Peanut - dietary (substance), Severity: Severe, Details: Reported by Mother, Start: Apr 01, 2012 + + + + + + + + + + + + + + + + + + + + Peanut - dietary (substance) + + + + + + + Reported by Mother + + + + + + + + + + + + + Confirmed present + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Amoxicillin + + + + + + + Presented in clinic with hives + + + + + + + + + + + + + Confirmed present + + + + + + + + + + + + + + + + + + + + + + + + + + + Lactose - dietary (substance) + + + + + + + Reported by Mother + + + + + + + + + + + + + Confirmed present + + + + + + + +
+
+ +
+ + + Clinical Measured Observations [with entries] + Weight: 11.3kg, Height: 82.5cm, BMI: 16.6, Pulse (bpm): 136, BP: 90/60, Temp: 38.4C - Oral, Date: Nov 01, 2013 + + + + + + + + + + + Body height + + + + + + + + + + + Body weight + + + + + + + + + + + Heart rate + + + + + + + + + + + Systolic blood pressure + + + + + + + + + + + Diastolic blood pressure + + + + + + + + + + + Body temperature + + + + + + + + + + + + Body mass index + + + + + + + + +
+
+ +
+ + + Encounter History [with entries] + Dec 20, 2012 - Acute cystitis, 68226007 (SNOMED CT) + +Notes: + Meds reviewed - added Clopidogrel. +Renewal of usual meds (left at hospital). +Keen to stop smoking and lose weight. +Pulse 60 /min +Regular? Yes +BP systolic 130 mm Hg +BP diastolic 85 mm Hg +Objective Note: Obese. +Chest, CVS and Abdominal exams negative. +Foot exam normal. +Assessment Note: CAD stable. +Suggested nicotine patch and stop Smoking Line. Consider dietician referral next visit. + +Dec 15, 2012 - Consult + +Notes: + History of Presenting Illness: +Ms. Jones is a 38 year old single woman who developed pain and stiffness in several joints 2 months prior to referral. She has noted that it is very difficult to open jars due to the pain in the fingers and wrists. She also has difficulty dressing herself because of shoulder and elbow stiffness. Walking is painful, particularly on the balls of her feet, and she has noted some swelling of her knees, bilaterally. She experiences 1 hour of morning stiffness. +She had some initial benefit from Naprosyn 375 mg PO BID, but found it upset her stomach, so stopped it about 3 weeks ago. +She cannot recall any antecedent illnesses, and was enjoying several sporting activities prior to onset, including bike riding and hiking. On closer questioning she denies any skin rashes, and has not noticed any gastrointestinal, cardiac, or pulmonary symptoms. +Medications/Allergies: She has not been on any medications for her condition however in the past she did take Penicillin for a “Strep Throat” and developed a widespread urticarial rash. She has not taken penicillin since. +Past Medical History: No known medical problems. Two normal pregnancies, vaginal delivery. +Past Surgical History: Appendectomy age 12; Cholecystectomy age 35 +Family History: +A maternal aunt had Rheumatoid Arthritis. Her mother has diabetes mellitus. Her father suffered a heart attack in 2006, at the age of 68. She has two siblings, a brother 3 years older and a sister 2 years younger, both of whom are well. +Social History: +She smoked til age 30, at 1 ppd but no longer does. She drinks 4 glasses of wine per week. She was married but now divorced. She works in a flower shop. Her children are aged 15 and 18. +Review of systems: +There is no history of Raynaud’s phenomenon, photosensitivity skin rashes, mouth ulcers, or serositis of the heart, lungs, or mesentery. She has not had any diarrhea or bowel upset. Her weight is stable. She has not had psoriasis, nor other skin conditions except she did have resection of a melanoma at age 30. She has never had seizures and does not suffer from any mental illness. +Physical Exam: +Vitals: BP 135/75; P 70; Ht 1.61 m; Wt 63.4 kg BMI 24.5 RR 16 +H&N: No malar rash, telangiectasia, conjunctivitis, scleritis,parotitis, mouth ulcers, or lymphadenopathy. Sublingual salivary pool is normal and gingiva are normal. Thyroid gland is normal. +Chest: Clear to IPPA +CV: Physiological systolic murmurs over aortic valve. Normal S1 and S2. +Abdomen: Normal bowel sounds. Normal palpation. No hepato or splenomegaly. +Skin: Scar on back from melanoma removal. Fair complexion. No sclerodactyly, calcinosis, periungal erythema, or evidence of psoriasis. +Neuro: Normal CNS and PNS. No movement disorder. +MSK; 20 swollen and 22 tender joints out of 28 joint count. MCPs, PIPs and wrists bilaterally are swollen and tender. Both ankles are swollen and tender. Left knee has popliteal cyst. MTPs are tender. No deformities are evident. +Lab Results: Date – March 15, 2012 +RF 85; Anti-CCP high positive; ESR 45; Hgb 115; WBC 4.5 – PMN 3.0; WBC 1.3; Monos 0.2; Creatinine 74 +Diagnostic Imaging: March 25, 2012 No erosions seen on hand films but some periarticular osteopenia is noted. +Ultrasound Abdomen: March 28, 2012 – An obstetrical ultrasound of uterus was performed. Normal uterus, with no evidence of fetus or placenta. +Bone Density: 2010, June 30; Tscores: L spine -1.3; Femoral neck -1.0 +Pathology reports: Normal PAP smears in past 5 assessments; skin biopsy – melanoma with margins clear + + +Jun 12, 2012 - Cough and Fever + +Notes: +3 days cough and fever. Not eating well. No vomiting or diarrhea. Formula fed but taking baby food as well. +O/E Lethargic baby. Temp 39 degrees C. Not dehydrated. Resp rate 18. Some wheeze ut no indrawing. Crusty nose. Both Tm’s red and bulging. Pharynx red. No pus. Neck supple. Crusty eyes. +Ongoing microcephaly. +Weight: 5.2 kg +Head circ: 42. cm +Dx Influenza +BOM +Bronchiolitis +Rx Biaxin +Tylenol +Ventolin with aerochamber. +Advise mom to see public health for next vaccination. + + + + + + + + + + + + + + + + + + A. + Black + + + + + + + + + Cough and Fever + + + + + + + + + + + + + + + + Notes: 3 days cough and fever. Not eating well. No vomiting or diarrhea. Formula fed but taking baby food as well. +O/E Lethargic baby. Temp 39 degrees C. Not dehydrated. Resp rate 18. Some wheeze ut no indrawing. Crusty nose. Both Tm’s red and bulging. Pharynx red. No pus. Neck supple. Crusty eyes. +Ongoing microcephaly. +Weight: 5.2 kg +Head circ: 42. cm +Dx Influenza +BOM +Bronchiolitis +Rx Biaxin +Tylenol +Ventolin with aerochamber. +Advise mom to see public health for next vaccination. + + + + + + + + + + + + + + + + + + + + + + + A. + Black + + + + + + + + + Consult + + + + + + + + + + + + + + + + Notes: History of Presenting Illness: +Ms. Jones is a 38 year old single woman who developed pain and stiffness in several joints 2 months prior to referral. She has noted that it is very difficult to open jars due to the pain in the fingers and wrists. She also has difficulty dressing herself because of shoulder and elbow stiffness. Walking is painful, particularly on the balls of her feet, and she has noted some swelling of her knees, bilaterally. She experiences 1 hour of morning stiffness. +She had some initial benefit from Naprosyn 375 mg PO BID, but found it upset her stomach, so stopped it about 3 weeks ago. +She cannot recall any antecedent illnesses, and was enjoying several sporting activities prior to onset, including bike riding and hiking. On closer questioning she denies any skin rashes, and has not noticed any gastrointestinal, cardiac, or pulmonary symptoms. +Medications/Allergies: She has not been on any medications for her condition however in the past she did take Penicillin for a “Strep Throat” and developed a widespread urticarial rash. She has not taken penicillin since. +Past Medical History: No known medical problems. Two normal pregnancies, vaginal delivery. +Past Surgical History: Appendectomy age 12; Cholecystectomy age 35 +Family History: +A maternal aunt had Rheumatoid Arthritis. Her mother has diabetes mellitus. Her father suffered a heart attack in 2006, at the age of 68. She has two siblings, a brother 3 years older and a sister 2 years younger, both of whom are well. +Social History: +She smoked til age 30, at 1 ppd but no longer does. She drinks 4 glasses of wine per week. She was married but now divorced. She works in a flower shop. Her children are aged 15 and 18. +Review of systems: +There is no history of Raynaud’s phenomenon, photosensitivity skin rashes, mouth ulcers, or serositis of the heart, lungs, or mesentery. She has not had any diarrhea or bowel upset. Her weight is stable. She has not had psoriasis, nor other skin conditions except she did have resection of a melanoma at age 30. She has never had seizures and does not suffer from any mental illness. +Physical Exam: +Vitals: BP 135/75; P 70; Ht 1.61 m; Wt 63.4 kg BMI 24.5 RR 16 +H&N: No malar rash, telangiectasia, conjunctivitis, scleritis,parotitis, mouth ulcers, or lymphadenopathy. Sublingual salivary pool is normal and gingiva are normal. Thyroid gland is normal. +Chest: Clear to IPPA +CV: Physiological systolic murmurs over aortic valve. Normal S1 and S2. +Abdomen: Normal bowel sounds. Normal palpation. No hepato or splenomegaly. +Skin: Scar on back from melanoma removal. Fair complexion. No sclerodactyly, calcinosis, periungal erythema, or evidence of psoriasis. +Neuro: Normal CNS and PNS. No movement disorder. +MSK; 20 swollen and 22 tender joints out of 28 joint count. MCPs, PIPs and wrists bilaterally are swollen and tender. Both ankles are swollen and tender. Left knee has popliteal cyst. MTPs are tender. No deformities are evident. +Lab Results: Date – March 15, 2012 +RF 85; Anti-CCP high positive; ESR 45; Hgb 115; WBC 4.5 – PMN 3.0; WBC 1.3; Monos 0.2; Creatinine 74 +Diagnostic Imaging: March 25, 2012 No erosions seen on hand films but some periarticular osteopenia is noted. +Ultrasound Abdomen: March 28, 2012 – An obstetrical ultrasound of uterus was performed. Normal uterus, with no evidence of fetus or placenta. +Bone Density: 2010, June 30; Tscores: L spine -1.3; Femoral neck -1.0 +Pathology reports: Normal PAP smears in past 5 assessments; skin biopsy – melanoma with margins clear + + + + + + + + + + + + + + + + + + + + + + + + Susan + Gold + + + + + + + + + Acute cystitis, 68226007 (SNOMED CT) + + + + + + + + + + + + + + + + Notes: Meds reviewed - added Clopidogrel. +Renewal of usual meds (left at hospital). +Keen to stop smoking and lose weight. +Pulse 60 /min +Regular? Yes +BP systolic 130 mm Hg +BP diastolic 85 mm Hg +Objective Note: Obese. +Chest, CVS and Abdominal exams negative. +Foot exam normal. +Assessment Note: CAD stable. +Suggested nicotine patch and stop Smoking Line. Consider dietician referral next visit. + + + + + +
+
+ +
+ + + Family History [with entries] + Mother: Fetal alcohol syndrome, Age at Onset: 0, Comment: Family history of alcoholism, refusal for treatment, Cause of Death: Cirrhosis(liver) +Natural Mother: Family history of cancer of colon, Age at Onset: 54, Comment: Mom was diagnosed with metastatic cancer of colon and died at age 55., Age at Death: 55, Cause of Death: Cancer of colon, +Natural Mother: Diabetes mellitus, Comment: Family history of obesity with extremely poor diet during childhood, due to lack of education and financial hardship, Cause of Death: Kidney Disease + + + + + + Fetal alcohol syndrome + + + + + + + + + + + Family history of alcoholism, refusal for treatment + + + + + + + + + + + + + Cirrhosis(liver) + + + + + + + + + + Family history of cancer of colon + + + + + + + + + + + Mom was diagnosed with metastatic cancer of colon and died at age 55. + + + + + + + + + + + + + + + + + + + Cancer of colon, + + + + + + + + + + Diabetes mellitus + + + + + + + + + + + Family history of obesity with extremely poor diet during childhood, due to lack of education and financial hardship + + + + + + + Kidney Disease + + + + +
+
+ +
+ + + Immunizations List [with entries] + Pentacel: Patient’s Mother is extremely nervous. - Date: Mar 10, 2014, Series #: 2 of 3, Lot #: A41CA687A., Facility: Conform Family Clinic +Rotavirus (oral) - Date: Apr 17, 2012, Series #: 1 of 2, Lot #: 5551212, Facility: Primary Office +VZ (Varicella Zoster): Patient refused vaccine due to fear of needles. - Date: Jun 21, 2011, Refused Immunization, Series #: 1 of 1, Lot #: U1768AA, Facility: Family Practice Clinic + + + + + + + + + + + Rotavirus (oral) + 5551212 + + + + + + + + + + Primary Office + + + + + + + + + + + + + + + Rotavirus (oral) + + + + + + + + + + + + + + + Left Arm + + + + + + Pentacel + A41CA687A. + + + + + + + + + + Conform Family Clinic + + + + + + + + + + + + + + + Pentacel + + + + + + + + + Patient’s Mother is extremely nervous. + + + + + + + + + + + + + Right Arm + + + + + + Varicella Zoster + U1768AA + + + + + + + + + + Family Practice Clinic + + + + + + + + + + + + + + + Varicella Zoster + + + + + + + + + + Patient Refused + + + + + + + + Patient refused vaccine due to fear of needles. + + + + + +
+
+ +
+ + + Laboratory Results and Reports [with entries] + Mar 12 2012 1:01PM + Hematology Panel + Ordering Provider: MDCARE, BOB + Lab OBR Status: Completed + WBC 6690-2: 9.3 giga/L, Range: 4.0-10.0 + Interpretation Code: Normal + RBC 789-8: 4.88 tera/L, Range: 3.80-4.80 + Interpretation Code: Abnormal + Hemoglobin 718-7: 116 g/L, Range: 120-150 + Interpretation Code: Abnormal + Hematocrit 4544-3: 0.37, Range: 0.35-0.43 + Interpretation Code: Normal + MCV 787-2: 76 fl, Range: 82-98 + Interpretation Code: Abnormal + MCH 785-6: 23.8 pg, Range: 27.5-33.5 + Interpretation Code: Abnormal + MCHC 786-4: 311 g/L, Range: 305-365 + Interpretation Code: Normal + RDW 788-0: 15.7 %, Range: 11.5-14.5 + Interpretation Code: Abnormal + Platelet Count 777-3: 253 giga/L, Range: 150-400 + Interpretation Code: Normal + Neutrophils 751-8: 5.3 giga/L, Range: 2.0-7.5 + Interpretation Code: Normal + Lymphocytes 731-0: 3.2 giga/L, Range: 1.0-4.0 + Interpretation Code: Normal + Monocytes 742-7: 0.6 giga/L, Range: 0.1-0.8 + Interpretation Code: Normal + Eosinophils 711-2: 0.1 giga/L, Range: 0.0-0.7 + Interpretation Code: Normal + Basophils 704-7: 0.0 giga/L, Range: 0.0-0.2 + Interpretation Code: Normal + +Mar 12 2012 1:01PM + Ferritin + Ordering Provider: MDCARE, BOB + Lab OBR Status: Completed + Ferritin 2276-4: <5 ug/L, Range: 15-180 + Interpretation Code: Abnormal + Notes: + Serum ferritin is the recommended single\.br\test to diagnose iron deficiency.\.br\ + +Mar 12 2012 1:01PM + Glucose Fasting + Ordering Provider: MDCARE, BOB + Lab OBR Status: Completed + Glucose Fasting 14771-0: 4.8 mmol/L, Range: 3.3-5.5 + Interpretation Code: Normal + +Mar 12 2012 1:01PM + Lipids + Ordering Provider: MDCARE, BOB + Lab OBR Note: Fasting?: YES + Lab OBR Status: Completed + Cholesterol 14647-2: 3.98 mmol/L, Range: 2.00-4.59 + Interpretation Code: Normal + LDL Cholesterol 39469-2: 1.98 mmol/L, Range: 1.50-2.99 + Interpretation Code: Normal + Notes: + The LDL-C target for moderate and high\.br\risk individuals is less than 2.0 mmol/L\.br\or a reduction of 50% or more. For low \.br\risk individuals, the LDL-C target is a \.br\reduction of 50% or more. See Can. J. \.br\Cardiol. 2009\.br\25(10):567-569.\.br\ + HDL Cholesterol 14646-4: 1.71 mmol/L, Range: >1.10 + Interpretation Code: Normal + Chol/HDL (Risk Ratio) 32309-7: 2.33, Range: <4.4 + Interpretation Code: Normal + Triglycerides 14927-8: 0.64 mmol/L, Range: 0.45-2.29 + Interpretation Code: Normal + +Mar 12 2012 1:01PM + TSH + Ordering Provider: MDCARE, BOB + Lab OBR Status: Completed + TSH 3016-3: 3.0 mU/L, Range: 0.38-5.5 + Interpretation Code: Normal + +Mar 12 2012 1:01PM + Free T4 + Ordering Provider: MDCARE, BOB + Lab OBR Status: Completed + Free T4 14920-3: 13.3 pmol/L, Range: 10.5-20.0 + Interpretation Code: Normal + +Jan 11 2012 11:19AM + Urine Drug/Ethanol Screen + Ordering Provider: MDCARE, BOB + Lab OBR Note: This method does not detect Oxycodone. Please order Oxycodone, if needed.\.br\URINE DRUG SCREENS\.br\Specimens for Urine Drug Screens will be stored for 2 weeks.\.br\Please call if confirmatory or additional testing is required.\.br\MSP requires clinical indications/justification for confirmatory testing.\.br\This Urine Drug Screen is not valid for legal purposes. + Lab OBR Status: Completed + Amphetamines 19261-7: neg. + Interpretation Code: Normal + Benzodiazepines 14316-4: neg. + Interpretation Code: Normal + Cocaine 19359-9: neg. + Interpretation Code: Normal + Opiates 19295-5: POS. + Interpretation Code: Normal + Oxycodone 19642-8: neg. + Interpretation Code: Normal + Methadone+Metabolite 42251-9: POS. + Interpretation Code: Normal + Test Comment X10083: * + Interpretation Code: Normal + +Apr 11 2012 8:43AM + General Information + Ordering Provider: MDCARE, BOB + Lab OBR Note: Ciprofloxacin, Levofloxacin, Moxifloxacin and Norfloxacin are not recommended for children <18 years of age. \.br\\.br\Partial resistance to quinolones may not be detected by standard susceptibility testing methods. Quinolones should be avoided or used with caution if history of recent quinolone use. \.br\\.br\2 + Oropharyngeal flora also present. \.br\\.br\Ph''d by: LL Rec''d by: Dr\.br\Date: 11Apr12 Time: 0845 \.br\\.br\Clinical Information: Excelleris Testing + Lab OBR Status: Completed + +Apr 11 2012 8:43AM + Sputum Culture + Ordering Provider: MDCARE, BOB + Lab OBR Status: Completed + Site 19803-6: Source: Sputum + Gram Stain 664-3: Gram Stain: + Gram Stain 664-3: 2+ White Blood Cells + Gram Stain 664-3: 1+ Epithelial Cells + Gram Stain 664-3: 3+ Gram Positive Cocci + Gram Stain 664-3: 3+ Gram Negative Bacilli + Gram Stain 664-3: Specimen suitable for culture. + Culture 6463-4: No MRSA isolated. + Notes: + Culture results may be unrepresentative due to delay in transport. + Organism XBC19-0: Streptococcus pneumoniae 3+ Growth + Notes: + Penicillin Sensitive (meningitis)\.br\Penicillin Sensitive (non-meningitis)\.br\Penicillin Sensitive (oral)\.br\ + Amoxicillin 16-6: S + Erythromycin 233-7: S + Trimethoprim-Sulfa 516-5: S + Levofloxacin 20396-8: S + Organism XBC19-0: Klebsiella pneumoniae (AMPC) 4+ Growth + Notes: + POSITIVE FOR AMP C CEPHALOSPORINASE.\.br\Infection Control notified.\.br\This organism is resistant to all penicillins, cephalosporins, aztreonam and beta-lactamase inhibitor combination drugs.\.br\This isolate is also SENSITIVE to Imipenem. + Ampicillin 28-1: R + Amoxicillin-Clavulanate 20-8: R + Cefazolin 76-0: R + Cephalothin-Cephalexin X10042: R + Cefixime 80-2: R + Ceftriaxone 141-2: R + Piperacillin-Tazobactam 412-7: R + Meropenem 6652-2: S + Ertapenem 35801-0: S + Trimethoprim-Sulfa 516-5: S + Ciprofloxacin 185-9: R + Gentamicin 267-5: R + Tobramycin 508-2: R + Amikacin 12-5: S + + + + + + Hematology Panel + + + + + + + + + + + + + + WBC + + + + + 9.3 giga/L + + + + 4.0-10.0 + + + + + + + + + + RBC + + + + + 4.88 tera/L + + + + 3.80-4.80 + + + + + + + + + + Hemoglobin + + + + + 116 g/L + + + + 120-150 + + + + + + + + + + Hematocrit + + + + + 0.37 + + + + 0.35-0.43 + + + + + + + + + + MCV + + + + + 76 fl + + + + 82-98 + + + + + + + + + + MCH + + + + + 23.8 pg + + + + 27.5-33.5 + + + + + + + + + + MCHC + + + + + 311 g/L + + + + 305-365 + + + + + + + + + + RDW + + + + + 15.7 % + + + + 11.5-14.5 + + + + + + + + + + Platelet Count + + + + + 253 giga/L + + + + 150-400 + + + + + + + + + + Neutrophils + + + + + 5.3 giga/L + + + + 2.0-7.5 + + + + + + + + + + Lymphocytes + + + + + 3.2 giga/L + + + + 1.0-4.0 + + + + + + + + + + Monocytes + + + + + 0.6 giga/L + + + + 0.1-0.8 + + + + + + + + + + Eosinophils + + + + + 0.1 giga/L + + + + 0.0-0.7 + + + + + + + + + + Basophils + + + + + 0.0 giga/L + + + + 0.0-0.2 + + + + + + + + + + + + + + Ferritin + + + + + + + + + + + + + + Ferritin + + + + + <5 ug/L + + + + + Serum ferritin is the recommended single\.br\test to diagnose iron deficiency.\.br\ + + + + + + 15-180 + + + + + + + + + + + + + + Glucose Fasting + + + + + + + + + + + + + + Glucose Fasting + + + + + 4.8 mmol/L + + + + 3.3-5.5 + + + + + + + + + + + + + + Lipids + + + + + + Fasting?: YES + + + + + + + + + + + + + + + Cholesterol + + + + + 3.98 mmol/L + + + + 2.00-4.59 + + + + + + + + + + LDL Cholesterol + + + + + 1.98 mmol/L + + + + + The LDL-C target for moderate and high\.br\risk individuals is less than 2.0 mmol/L\.br\or a reduction of 50% or more. For low \.br\risk individuals, the LDL-C target is a \.br\reduction of 50% or more. See Can. J. \.br\Cardiol. 2009\.br\25(10):567-569.\.br\ + + + + + + 1.50-2.99 + + + + + + + + + + HDL Cholesterol + + + + + 1.71 mmol/L + + + + >1.10 + + + + + + + + + + Chol/HDL (Risk Ratio) + + + + + 2.33 + + + + <4.4 + + + + + + + + + + Triglycerides + + + + + 0.64 mmol/L + + + + 0.45-2.29 + + + + + + + + + + + + + + TSH + + + + + + + + + + + + + + TSH + + + + + 3.0 mU/L + + + + 0.38-5.5 + + + + + + + + + + + + + + Free T4 + + + + + + + + + + + + + + Free T4 + + + + + 13.3 pmol/L + + + + 10.5-20.0 + + + + + + + + + + + + + + Urine Drug/Ethanol Screen + + + + + + This method does not detect Oxycodone. Please order Oxycodone, if needed.\.br\URINE DRUG SCREENS\.br\Specimens for Urine Drug Screens will be stored for 2 weeks.\.br\Please call if confirmatory or additional testing is required.\.br\MSP requires clinical indications/justification for confirmatory testing.\.br\This Urine Drug Screen is not valid for legal purposes. + + + + + + + + + + + + + + + Amphetamines + + + + + neg. + + + + + + + + + Benzodiazepines + + + + + neg. + + + + + + + + + Cocaine + + + + + neg. + + + + + + + + + Opiates + + + + + POS. + + + + + + + + + Oxycodone + + + + + neg. + + + + + + + + + Methadone+Metabolite + + + + + POS. + + + + + + + + + Test Comment + + + + + * + + + + + + + + + + + + + General Information + + + + + + Ciprofloxacin, Levofloxacin, Moxifloxacin and Norfloxacin are not recommended for children <18 years of age. \.br\\.br\Partial resistance to quinolones may not be detected by standard susceptibility testing methods. Quinolones should be avoided or used with caution if history of recent quinolone use. \.br\\.br\2 + Oropharyngeal flora also present. \.br\\.br\Ph''d by: LL Rec''d by: Dr\.br\Date: 11Apr12 Time: 0845 \.br\\.br\Clinical Information: Excelleris Testing + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sputum Culture + + + + + + + + + + + + + + Site + + + + + Source: Sputum + + + + + + + + Gram Stain + + + + + Gram Stain: + + + + + + + + Gram Stain + + + + + 2+ White Blood Cells + + + + + + + + Gram Stain + + + + + 1+ Epithelial Cells + + + + + + + + Gram Stain + + + + + 3+ Gram Positive Cocci + + + + + + + + Gram Stain + + + + + 3+ Gram Negative Bacilli + + + + + + + + Gram Stain + + + + + Specimen suitable for culture. + + + + + + + + Culture + + + + + No MRSA isolated. + + + + Culture results may be unrepresentative due to delay in transport. + + + + + + + + + + + Organism + + + + + Streptococcus pneumoniae 3+ Growth + + + + Penicillin Sensitive (meningitis)\.br\Penicillin Sensitive (non-meningitis)\.br\Penicillin Sensitive (oral)\.br\ + + + + + + + + + + + Amoxicillin + + + + + S + + + + + + + + Erythromycin + + + + + S + + + + + + + + Trimethoprim-Sulfa + + + + + S + + + + + + + + Levofloxacin + + + + + S + + + + + + + + Organism + + + + + Klebsiella pneumoniae (AMPC) 4+ Growth + + + + POSITIVE FOR AMP C CEPHALOSPORINASE.\.br\Infection Control notified.\.br\This organism is resistant to all penicillins, cephalosporins, aztreonam and beta-lactamase inhibitor combination drugs.\.br\This isolate is also SENSITIVE to Imipenem. + + + + + + + + + + + Ampicillin + + + + + R + + + + + + + + Amoxicillin-Clavulanate + + + + + R + + + + + + + + Cefazolin + + + + + R + + + + + + + + Cephalothin-Cephalexin + + + + + R + + + + + + + + Cefixime + + + + + R + + + + + + + + Ceftriaxone + + + + + R + + + + + + + + Piperacillin-Tazobactam + + + + + R + + + + + + + + Meropenem + + + + + S + + + + + + + + Ertapenem + + + + + S + + + + + + + + Trimethoprim-Sulfa + + + + + S + + + + + + + + Ciprofloxacin + + + + + R + + + + + + + + Gentamicin + + + + + R + + + + + + + + Tobramycin + + + + + R + + + + + + + + Amikacin + + + + + S + + + + + + +
+
+ +
+ + + Medications & Prescriptions - Medication List [with entries] + ERYTHRO-BASE, Directions: 1x 1 Tablet(s) Four times daily, Repeats: 0, Details: Take with Food +Melatonin 5mg capsule, Directions: 1x 5 Mg Once daily PRN, Repeats: 0, Details: One capsule daily at bedtime as needed +. Take at bedtime +KENALOG-10 INJECTION 10MG/ML, Directions: 1x 5 Mg Once a month intra-articularly, Repeats: 0, Details: 5mg administered intra-articularly to right foot monthly. Bring medication to Doctor's office for administration. +DOM-SALBUTAMOL 5MG/ML SOLN, Directions: 1x 1 Millilitres Twice daily, Repeats: 0, Details: 1ml with 5ml Normal saline by Nebulizer twice daily. +VENTOLIN HFA, Directions: 1x 100 Mcg Four times daily, Repeats: 0, Details: 1-2 Puffs four times daily for 30 days. Use with Aerochamber + + + + + + + + + + + + VENTOLIN HFA + + + + + + + Patient uses an Aerochamber with Inhaler + + + + + + + + + + + + + + + + VENTOLIN HFA + + + + + + + + + [Frequency: Four times daily] + +
+ + + + + + + VENTOLIN HFA + + + + + + + + + + + + + + + + + + 1-2 Puffs four times daily for 30 days. Use with Aerochamber + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ERYTHRO-BASE + + + + + + + + + + + + + + + + + + + + + + ERYTHRO-BASE + + + + + + + + + [Frequency: Four times daily] + +
+ + + + + + + ERYTHRO-BASE + + + + + + + + + + + + + + + + + + Take with Food + + + + + + + + + + + + + + + + + + + + + + + Melatonin 5mg capsule + + + + + + + + + + + + + + + + + + + + + + Melatonin 5mg capsule + + + + + + + + + [Frequency: Once daily] + +
+ + + + + + + Melatonin 5mg capsule + + + + + + + + + + + + + + + + + + One capsule daily at bedtime as needed +. Take at bedtime + + + + + + + + + + + + + + + + + + + + + + + AMOXICILLIN 125MG/5ML SUSP + + + + + + + + + + + + + + + + + + + + + + + AMOXICILLIN 125MG/5ML SUSP + + + + + + + + + [Frequency: Three times daily] + +
+ + + + + + + AMOXICILLIN 125MG/5ML SUSP + + + + + + + + + + + + + + + + + + 125mg (5ml) three times daily +. Shake well before use and take until finished + + + + + + + + + + + + + + + + + + + + + + + DOM-SALBUTAMOL 5MG/ML SOLN + + + + + + + Requested patient education session with Respiratory Tech at hospital. + + + + + + + + + + + + + + + + DOM-SALBUTAMOL 5MG/ML SOLN + + + + + + + + + [Frequency: Twice daily] + +
+ + + + + + + DOM-SALBUTAMOL 5MG/ML SOLN + + + + + + + + + + + + + + + + + + 1ml with 5ml Normal saline by Nebulizer twice daily. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + KENALOG-10 INJECTION 10MG/ML + + + + + + + + + + + + + + + + + + + + + + KENALOG-10 INJECTION 10MG/ML + + + + + + + + + [Frequency: Once a month] + + intra-articularly + + +
+ + + + + + + KENALOG-10 INJECTION 10MG/ML + + + + + + + + + + + + + + + + + + 5mg administered intra-articularly to right foot monthly. Bring medication to Doctor's office for administration. + + + + + + + + + + + + + + + + + + + + + + + APO-METHYLPHENIDATE + + + + + + + + + + + + + + + + + + + + + + + APO-METHYLPHENIDATE + + + + + + + + + [Frequency: Twice daily] + +
+ + + + + + + APO-METHYLPHENIDATE + + + + + + + + + + + + + + + + + + 5mg twice daily. + + + + + + + + + + + +
+
+ +
+ + + Orders & Requests [with entries] + Referral: Practitioner Number: 91001 To 98745 +Attached: documents\OrderResultsSample1.pdf +Reason: Fetal Alcohol syndrome +Referral Date: Apr/17/2012 15:15 +Status: Completed +Priority: Routine +Notes: Please arrange appt +Result Notes Client has undergone psychosocial evaluation. SW currently determining need for provision or arrangement of support services to the family. +supervising the child's care in the home, or +protecting the child through removal from the family and placement with relatives, a foster family or specialized residential resources. + +Referral: Practitioner Number: 91001 To 98712 +Attached: documents\OrderResultsSample2.pdf +Reason: Family history of cancer of colon +Referral Date: Mar/06/2014 13:53 +Status: Active +Priority: Routine +Notes: You have seen this lady 5 years ago. She had clear colonoscopy then. Due again. +Result Notes Evidence of several 3-4 small adenomatous polyps less than 1 cm. +Specimen biopsy to determine malignancy. + +Referral: Practitioner Number: 91001 To 98345 +Attached: documents\OrderResultSample3.pdf +Reason: Daily Living Activities Therapy +Referral Date: Feb/12/2009 13:58 +Status: Suspended +Priority: Routine +Notes: Patient is experiencing difficulty at home in activities of daily living +Result Notes Client scored low in Assessment of Motor and Process Skills (AMPS) and will require a 3 week program for 3 days per week, with re-assessment week 4, utilizing guidelines from Canadian Occupational Performance Measure (COPM) + + + + + + Referral + + + + + + + + + + + + + + + + + Fetal Alcohol syndrome + + + + + + + + + + + + + + Please arrange appt +Result Notes Client has undergone psychosocial evaluation. SW currently determining need for provision or arrangement of support services to the family. +supervising the child's care in the home, or +protecting the child through removal from the family and placement with relatives, a foster family or specialized residential resources. + + + + + + + + + + + Referral + + + + + + + + + + + + + + + + + Family history of cancer of colon + + + + + + + + + + + + + + You have seen this lady 5 years ago. She had clear colonoscopy then. Due again. +Result Notes Evidence of several 3-4 small adenomatous polyps less than 1 cm. +Specimen biopsy to determine malignancy. + + + + + + + + + + + Referral + + + + + + + + + + + + + + + + + Daily Living Activities Therapy + + + + + + + + + + + + + + Patient is experiencing difficulty at home in activities of daily living +Result Notes Client scored low in Assessment of Motor and Process Skills (AMPS) and will require a 3 week program for 3 days per week, with re-assessment week 4, utilizing guidelines from Canadian Occupational Performance Measure (COPM) + + + + + +
+
+ +
+ + + Problems & Conditions - Problem List [with entries] + Fetal alcohol syndrome: Hx positive and mets clinical criteria, Start: Jan 21, 2012 +Diabetes mellitus type 1, Start: Oct 10, 2011 +Diabetes mellitus: Terrible control. Overweight and sedentary. No monitoring., Start: Dec 31, 2009 +Hypertensive disorder, systemic arterial: Moderate severity. BP generally a bit high despite meds., Start: Aug 14, 2001, End: Aug 14, 2001 +Asthma + + + + + + Diabetes mellitus type 1 + + + + + + + + + + + + + + + + + + + + Asthma + + + + + + + + + + + + + + + + + Fetal alcohol syndrome + + + + + + + + + + + + + + + Hx positive and mets clinical criteria + + + + + + + + + + Hypertensive disorder, systemic arterial + + + + + + + + + + + + + + + + + Moderate severity. BP generally a bit high despite meds. + + + + + + + + + + Diabetes mellitus + + + + + + + + + + + + + + + + Terrible control. Overweight and sedentary. No monitoring. + + + + +
+
+ +
+ + + Risk Factors [with entries] + Pediatric Obesity: Pediatric Obesity Risk Factors: + Diet : Yes + Lack of exercise : Yes + Family history : Yes + Psychological factors : Yes + Family factors. : Yes + Socioeconomic factors : Yes + + + + + + + + + + Pediatric Obesity + + + + [Risk Comments: Pediatric Obesity Risk Factors: + Diet : Yes + Lack of exercise : Yes + Family history : Yes + Psychological factors : Yes + Family factors. : Yes + Socioeconomic factors : Yes] + + + + +
+
+
+
+
\ No newline at end of file diff --git a/test/fixtures/map_reduce/simple_reduce.js b/test/fixtures/map_reduce/simple_reduce.js index ac1a37e..3fb7c33 100644 --- a/test/fixtures/map_reduce/simple_reduce.js +++ b/test/fixtures/map_reduce/simple_reduce.js @@ -1,7 +1,3 @@ function reduce(gender, counts) { - var sum = 0; - while(counts.hasNext()){ - sum += counts.next(); - } - return sum; + return Array.sum(counts); }; \ No newline at end of file diff --git a/test/fixtures/pdc/bmi_wc_map.js b/test/fixtures/pdc/bmi_wc_map.js new file mode 100644 index 0000000..f6b990d --- /dev/null +++ b/test/fixtures/pdc/bmi_wc_map.js @@ -0,0 +1,72 @@ +// Reference Number: PDC-009 +// Query Title: BMI or WC documented in last 2 yrs age > 19 +function map(patient) { + var targetWaistCircumferenceCodes = { + "LOINC": ["56115-9"] + }; + + var targetHeightCodes = { + "LOINC": ["8302-2"] + }; + + var targetWeightCodes = { + "LOINC": ["3141-9"] + }; + + var targetBMICodes = { + "LOINC": ["39156-5"] + }; + + var ageLimit = 19; + + var vitalSignList = patient.vitalSigns(); + + var now = new Date(2013, 10, 30); + var start = addDate(now, -2, 0, 0); + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks if patient is older than ageLimit + function population(patient) { + return (patient.age(now) > ageLimit); + } + + function hasWaistCircumference() { + return vitalSignList.match(targetWaistCircumferenceCodes, start, end).length; + } + + function hasHeight() { + return vitalSignList.match(targetHeightCodes, start, end).length; + } + + function hasWeight() { + return vitalSignList.match(targetWeightCodes, start, end).length; + } + + function hasBMI() { + return vitalSignList.match(targetBMICodes, start, end).length; + } + + function hasRecordedValues() { + return hasWaistCircumference() || hasBMI() || (hasHeight() && hasWeight()); + } + + if (population(patient)) { + emit("denominator_patients_>19", 1); + if (hasRecordedValues()) { + emit("numerator_has_recorded_values", 1); + } + } + + // Empty Case + emit("numerator_has_recorded_values", 0); + emit("denominator_patients_>19", 0); +} \ No newline at end of file diff --git a/test/fixtures/pdc/colon_screening_map.js b/test/fixtures/pdc/colon_screening_map.js new file mode 100644 index 0000000..bf1ff00 --- /dev/null +++ b/test/fixtures/pdc/colon_screening_map.js @@ -0,0 +1,47 @@ +// Reference Number: PDC-020 +// Query Title: Practice population profile +// TODO: Add freetext definition search +// TODO: Add Colon screening portion of query +function map(patient) { + var targetLabCodes = { + "pCLOCD": ["58453-2", "14563-1", "14564-9", "14565-6"] + }; + + var ageLimitLow = 50; + var ageLimitHigh = 74; + var resultList = patient.results(); + + var now = new Date(2014, 6, 18); + var start = addDate(now, -2, 0, 0); + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks if patient is in target age range + function population(patient) { + return (patient.age(now) >= ageLimitLow && patient.age(now) <= ageLimitHigh); + } + + // Checks for Hemoccult labs performed within the last 2 years + function hasLabCode() { + return resultList.match(targetLabCodes, start, end).length; + } + + if (population(patient)) { + emit("denominator_patients_50-74", 1); + if (hasLabCode()) { + emit("numerator_has_hemoccult_result", 1); + } + } + + // Empty Case + emit("numerator_has_hemoccult_result", 0); + emit("denominator_patients_50-74", 0); +} diff --git a/test/fixtures/pdc/common_medication_map.js b/test/fixtures/pdc/common_medication_map.js new file mode 100644 index 0000000..f721122 --- /dev/null +++ b/test/fixtures/pdc/common_medication_map.js @@ -0,0 +1,71 @@ +// Reference Number: PDC-055 +// Query Title: Most commonly prescribed medication classes + +function map(patient) { + var atcLevel = 2; // Level definition based on definition found on Wikipedia + var atcCutoff = getATCCodeLength(atcLevel); + + var drugList = patient.medications(); + + var now = new Date(2013, 10, 30); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // a and b are javascript Date objects + // Returns a with the 1.2x calculated date offset added in + function endDateOffset(a, b) { + var start = new Date(a); + var end = new Date(b); + var diff = Math.floor((end - start) / (1000 * 3600 * 24)); + var offset = Math.floor(1.2 * diff); + return addDate(start, 0, 0, offset); + } + + function isCurrentDrug(drug) { + var drugStart = drug.indicateMedicationStart().getTime(); + var drugEnd = drug.indicateMedicationStop().getTime(); + + return (endDateOffset(drugStart, drugEnd) >= now && drugStart <= now); + } + + // Define ATC cutoff levels + function getATCCodeLength(val) { + switch (val) { + case 1: + return 1; + case 2: + return 3; + case 3: + return 4; + case 4: + return 5; + case 5: + return 7; + default: + return 0; + } + } + + for (var i = 0; i < drugList.length; i++) { + if (isCurrentDrug(drugList[i])) { + // Get all represented codes for each drug + var codes = drugList[i].medicationInformation().codedProduct(); + + // Filter out only ATC codes + for (var j = 0; j < codes.length; j++) { + if (codes[j].codeSystemName().toLowerCase() !== null && + codes[j].codeSystemName().toLowerCase() === "whoATC".toLowerCase()) { + // Truncate to appropriate level length + emit(codes[j].code().substring(0, atcCutoff), 1); + } + } + } + } +} diff --git a/test/fixtures/pdc/diabetes_bp_map.js b/test/fixtures/pdc/diabetes_bp_map.js new file mode 100644 index 0000000..e96ef6d --- /dev/null +++ b/test/fixtures/pdc/diabetes_bp_map.js @@ -0,0 +1,107 @@ +// Reference Number: PDC-028 +// Query Title: Diabetes & BP <= 130/80 in last yr + +function map(patient) { + + var targetBloodPressureSystolicCodes = { + "LOINC": ["8480-6"] + }; + + var targetBloodPressureDiastolicCodes = { + "LOINC": ["8462-4"] + }; + + var targetProblemCodes = { + "ICD9": ["250*"] + }; + + var bpSystolicLimit = 130; + var bpDiastolicLimit = 80; + + var problemList = patient.conditions(); + var vitalSignList = patient.vitalSigns(); + + var now = new Date(2013, 10, 30); + var start = addDate(now, -1, 0, 0); // last 12 months + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks if patient is older than ageLimit + function population() { + return true; + } + + // Checks for existence of systolic blood pressure observation + function hasSystolicBloodPressure() { + return vitalSignList.match(targetBloodPressureSystolicCodes, start, end).length; + } + + // Checks for existence of diastolic blood pressure observation + function hasDiastolicBloodPressure() { + return vitalSignList.match(targetBloodPressureDiastolicCodes, start, end).length; + } + + function hasBloodPressure() { + return hasSystolicBloodPressure() && hasDiastolicBloodPressure(); + } + + // Checks for diabetic patients + function hasProblemCode() { + return problemList.regex_match(targetProblemCodes).length; + } + + // Checks for Blood Pressure value matching conditions + // Systolic and diastolic records do not need to be sequential to return true + function hasBloodPressureMatchingIndicators() { + var bpSystolic = Number.MAX_VALUE; + var bpDiastolic = Number.MAX_VALUE; + for (var i = 0; i < vitalSignList.length; i++) { + if (vitalSignList[i].includesCodeFrom(targetBloodPressureSystolicCodes) && + vitalSignList[i].timeStamp() > start) { + if (vitalSignList[i].values()[0].units() !== null && + vitalSignList[i].values()[0].units().toLowerCase() === "mm[Hg]".toLowerCase()) { + if(vitalSignList[i].values()[0].scalar() < bpSystolic) { + bpSystolic = vitalSignList[i].values()[0].scalar(); + } + } + } else if (vitalSignList[i].includesCodeFrom(targetBloodPressureDiastolicCodes) && + vitalSignList[i].timeStamp() > start) { + if (vitalSignList[i].values()[0].units() !== null && + vitalSignList[i].values()[0].units().toLowerCase() === "mm[Hg]".toLowerCase()) { + if(vitalSignList[i].values()[0].scalar() < bpDiastolic) { + bpDiastolic = vitalSignList[i].values()[0].scalar(); + } + } + } + + if (bpSystolic > 0 && bpDiastolic > 0 && + bpSystolic <= bpSystolicLimit && bpDiastolic <= bpDiastolicLimit) { + return true + } + } + return false; + } + + emit('total_pop', 1); + + if (population()) { + if (hasProblemCode()) { + emit("denominator_diabetics", 1); + if (hasBloodPressure() && hasBloodPressureMatchingIndicators()) { + emit("numerator_diabetics_bp", 1); + } + } + } + + // Empty Case + emit("numerator_diabetics_bp", 0); + emit("denominator_diabetics", 0); +} \ No newline at end of file diff --git a/test/fixtures/pdc/diabetes_hgba1c_map.js b/test/fixtures/pdc/diabetes_hgba1c_map.js new file mode 100644 index 0000000..784eac3 --- /dev/null +++ b/test/fixtures/pdc/diabetes_hgba1c_map.js @@ -0,0 +1,49 @@ +// Reference Number: PDC-025 +// Query Title: Diabetics with HGBA1C in last 6 mo +// TODO: Add freetext definition search +function map(patient) { + var targetLabCodes = { + "pCLOCD": ["4548-4"] + }; + + var targetProblemCodes = { + "ICD9": ["250*"] + }; + + var resultList = patient.results(); + var problemList = patient.conditions(); + + var now = new Date(2013, 10, 30); + var start = addDate(now, 0, -6, 0); + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks for HGBA1C labs performed within the last 6 months + function hasLabCode() { + return resultList.match(targetLabCodes, start, end).length; + } + + // Checks for diabetic patients + function hasProblemCode() { + return problemList.regex_match(targetProblemCodes).length; + } + + if (hasProblemCode()) { + emit("denominator_diabetics", 1); + if(hasLabCode()) { + emit("numerator_has_hgba1c_result", 1); + } + } + + // Empty Case + emit("numerator_has_hgba1c_result", 0); + emit("denominator_diabetics", 0); +} diff --git a/test/fixtures/pdc/diabetes_hgba1c_value_map.js b/test/fixtures/pdc/diabetes_hgba1c_value_map.js new file mode 100644 index 0000000..3731b66 --- /dev/null +++ b/test/fixtures/pdc/diabetes_hgba1c_value_map.js @@ -0,0 +1,69 @@ +// Reference Number: PDC-026 +// Query Title: Diabetics with HGBA1C in last yr <= 7.0 +// TODO: Add freetext definition search +function map(patient) { + var targetLabCodes = { + "pCLOCD": ["4548-4"] + }; + + var targetProblemCodes = { + "ICD9": ["250*"] + }; + + var hgba1cLimit = 7; + + var resultList = patient.results(); + var problemList = patient.conditions(); + + var now = new Date(2013, 10, 30); + var start = addDate(now, -1, 0, 0); + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks for HGBA1C labs performed within the last year + function hasLabCode() { + return resultList.match(targetLabCodes, start, end).length; + } + + // Checks for diabetic patients + function hasProblemCode() { + return problemList.regex_match(targetProblemCodes).length; + } + + // Checks if HGBA1C meets parameters + function hasMatchingLabValue() { + for (var i = 0; i < resultList.length; i++) { + if (resultList[i].includesCodeFrom(targetLabCodes) && resultList[i].timeStamp() > start) { + if (resultList[i].values()[0].units() !== null && + resultList[i].values()[0].units().toLowerCase() === "%".toLowerCase()) { + if (resultList[i].values()[0].scalar() <= hgba1cLimit) { + return true; + } + } + } + } + return false; + } + + if (hasProblemCode()) { + emit("denominator_diabetics", 1); + if(hasLabCode()) { + emit("has_hgba1c_result", 1); + if(hasMatchingLabValue()) { + emit("numerator_has_matching_hgba1c_value", 1); + } + } + } + + // Empty Case + emit("numerator_has_matching_hgba1c_value", 0); + emit("denominator_diabetics", 0); +} diff --git a/test/fixtures/pdc/diabetes_ldl_map.js b/test/fixtures/pdc/diabetes_ldl_map.js new file mode 100644 index 0000000..0bd6a03 --- /dev/null +++ b/test/fixtures/pdc/diabetes_ldl_map.js @@ -0,0 +1,69 @@ +// Reference Number: PDC-027 +// Query Title: Diabetics with LDL in last yr <= 2.5 +// TODO: Add freetext definition search +function map(patient) { + var targetLabCodes = { + "pCLOCD": ["39469-2"] + }; + + var targetProblemCodes = { + "ICD9": ["250*"] + }; + + var ldlLimit = 2.5; + + var resultList = patient.results(); + var problemList = patient.conditions(); + + var now = new Date(2013, 10, 30); + var start = addDate(now, -1, 0, 0); + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks for ldl labs performed within the last year + function hasLabCode() { + return resultList.match(targetLabCodes, start, end).length; + } + + // Checks for diabetic patients + function hasProblemCode() { + return problemList.regex_match(targetProblemCodes).length; + } + + // Checks if ldl meets parameters + function hasMatchingLabValue() { + for (var i = 0; i < resultList.length; i++) { + if (resultList[i].includesCodeFrom(targetLabCodes) && resultList[i].timeStamp() > start) { + if (resultList[i].values()[0].units() !== null && + resultList[i].values()[0].units().toLowerCase() === "mmol/L".toLowerCase()) { + if (resultList[i].values()[0].scalar() <= ldlLimit) { + return true; + } + } + } + } + return false; + } + + if (hasProblemCode()) { + emit("denominator_diabetics", 1); + if(hasLabCode()) { + emit("has_ldl_result", 1); + if(hasMatchingLabValue()) { + emit("numerator_has_matching_ldl_value", 1); + } + } + } + + // Empty Case + emit("numerator_has_matching_ldl_value", 0); + emit("denominator_diabetics", 0); +} diff --git a/test/fixtures/pdc/fasting_blood_sugar_map.js b/test/fixtures/pdc/fasting_blood_sugar_map.js new file mode 100644 index 0000000..6eedc02 --- /dev/null +++ b/test/fixtures/pdc/fasting_blood_sugar_map.js @@ -0,0 +1,45 @@ +// Reference Number: PDC-022 +// Query Title: Fasting blood sugar in last 3 yrs age > 45 +// TODO: Add freetext definition search +function map(patient) { + var targetLabCodes = { + "pCLOCD": ["14771-0"] + }; + + var ageLimit = 45; + var resultList = patient.results(); + + var now = new Date(2013, 10, 30); + var start = addDate(now, -3, 0, 0); + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks if patient is older than ageLimit + function population(patient) { + return (patient.age(now) > ageLimit); + } + + // Checks for Fasting Blood Sugar labs performed within the last 3 years + function hasLabCode() { + return resultList.match(targetLabCodes, start, end).length; + } + + if (population(patient)) { + emit("denominator_patients_>45", 1); + if (hasLabCode()) { + emit("numerator_has_blood_sugar_result", 1); + } + } + + // Empty Case + emit("numerator_has_blood_sugar_result", 0); + emit("denominator_patients_>45", 0); +} diff --git a/test/fixtures/pdc/pdc_general_reduce.js b/test/fixtures/pdc/pdc_general_reduce.js new file mode 100644 index 0000000..f086eed --- /dev/null +++ b/test/fixtures/pdc/pdc_general_reduce.js @@ -0,0 +1,3 @@ +function reduce(key, values) { + return Array.sum(values); +} diff --git a/test/fixtures/pdc/pneumococcal_map.js b/test/fixtures/pdc/pneumococcal_map.js new file mode 100644 index 0000000..86c1809 --- /dev/null +++ b/test/fixtures/pdc/pneumococcal_map.js @@ -0,0 +1,39 @@ +// Reference Number: PDC-014 +// Query Title: Pneumococcal vaccination age 65+ +// TODO: Add freetext definition search +function map(patient) { + var targetImmunizationCodes = { + "whoATC": ["J07AL02"], + "SNOMED-CT": ["12866006", "394678003"] + }; + + var ageLimit = 64; + var immunizationList = patient.immunizations(); + + var now = new Date(2013, 10, 30); + + // Checks if patient is older than ageLimit + function population(patient) { + return (patient.age(now) > ageLimit); + } + + // Checks for existence of Pneumovax + function hasImmunization() { + return immunizationList.match(targetImmunizationCodes).length; + } + + if (hasImmunization()) { + emit("total_pneumovax", 1); + } + + if (population(patient)) { + emit("denominator_patients_>64", 1); + if (hasImmunization()) { + emit("numerator_senior_pop_pneumovax", 1); + } + } + + // Empty Case + emit("numerator_senior_pop_pneumovax", 0); + emit("denominator_patients_>64", 0); +} diff --git a/test/fixtures/pdc/polypharmacy_map.js b/test/fixtures/pdc/polypharmacy_map.js new file mode 100644 index 0000000..e8b3a5c --- /dev/null +++ b/test/fixtures/pdc/polypharmacy_map.js @@ -0,0 +1,87 @@ +// Reference Number: PDC-053 +// Query Title: Patients, 65 and older, on 5 or more medications +// Reference Number: PDC-054 +// Query Title: Patients, 65 and older, on 10 or more medications +function map(patient) { + var ageLimit = 65; + var drugLimit = 5; // Change this value to number of active medications to count + var now = new Date(2013, 10, 30); + + var drugList = patient.medications(); + var currentDrugs = findCurrentDrugs(drugList); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // a and b are javascript Date objects + // Returns a with the 1.2x calculated date offset added in + function endDateOffset(a, b) { + var start = new Date(a); + var end = new Date(b); + var diff = Math.floor((end-start) / (1000*3600*24)); + var offset = Math.floor(1.2 * diff); + return addDate(start, 0, 0, offset); + } + + function isCurrentDrug(drug) { + var drugStart = drug.indicateMedicationStart().getTime(); + var drugEnd = drug.indicateMedicationStop().getTime(); + + return (endDateOffset(drugStart, drugEnd) >= now && drugStart <= now); + } + + // Returns count of "active" drugs that are between start & end date + // Also checks for the same "active" drug and doesn't overcount + function findCurrentDrugs(drugs) { + var count = 0; + var seenDrugs = []; + + for(var i = 0; i < drugs.length; i++) { + var repeat = false; + + // Check if drug is within the right time + if(isCurrentDrug(drugs[i])) { + // Check if this entry is a repeat of same drug (codesystem agnostic) + var codes = drugs[i].medicationInformation().codedProduct(); + + for (var j = 0; j < codes.length; j++) { + var code = codes[j].code(); + + if(seenDrugs.indexOf(code) === -1) { + seenDrugs.push(code); + } + else { + repeat = true; + } + } + + // Increment count if not a repeat + if(!repeat) { + count++; + } + } + } + + return count; + } + + emit('total_population', 1); + if (patient.age(now) >= ageLimit) { + emit('denominator_sampled_number', 1); + + // Adds patient to count if over ageLimit & over drugLimit + if (currentDrugs >= drugLimit) { + emit('numerator_polypharmacy_number', 1); + } + } + + // Empty Case + emit('numerator_polypharmacy_number', 0); + emit('denominator_sampled_number', 0); +} diff --git a/test/fixtures/pdc/population_map.js b/test/fixtures/pdc/population_map.js new file mode 100644 index 0000000..58490ef --- /dev/null +++ b/test/fixtures/pdc/population_map.js @@ -0,0 +1,65 @@ +// Reference Number: PDC-001 +// Query Title: Practice population profile +// TODO: Factor in Clinical Encounters +function map(patient) { + var time = new Date(2013, 7, 19); + var age = patient.age(time); + var gender; + var genderValue = patient.gender(); + + if (typeof age !== 'undefined') { + age = Math.floor(age); + } + + if (genderValue !== null && genderValue !== undefined) { + if (patient.gender().toUpperCase() === "M") { + gender = "male"; + emit("total_male", 1); + } else if (patient.gender().toUpperCase() === "F") { + gender = "female"; + emit("total_female", 1); + } else { + gender = "undifferentiated"; + emit("total_undifferentiated", 1); + } + } else { + gender = "undifferentiated"; + emit("total_undifferentiated", 1); + } + + if(typeof age === 'undefined') { + emit("age_unspecified", 1); + } else if(age <= 9) { + if(gender !== "undifferentiated") emit(gender + "_0-9", 1); + emit("total_0-9", 1); + } else if(age >= 10 && age <= 19) { + if(gender !== "undifferentiated") emit(gender + "_10-19", 1); + emit("total_10-19", 1); + } else if(age >= 20 && age <= 29) { + if(gender !== "undifferentiated") emit(gender + "_20-29", 1); + emit("total_20-29", 1); + } else if(age >= 30 && age <= 39) { + if(gender !== "undifferentiated") emit(gender + "_30-39", 1); + emit("total_30-39", 1); + } else if(age >= 40 && age <= 49) { + if(gender !== "undifferentiated") emit(gender + "_40-49", 1); + emit("total_40-49", 1); + } else if(age >= 50 && age <= 59) { + if(gender !== "undifferentiated") emit(gender + "_50-59", 1); + emit("total_50-59", 1); + } else if(age >= 60 && age <= 69) { + if(gender !== "undifferentiated") emit(gender + "_60-69", 1); + emit("total_60-69", 1); + } else if(age >= 70 && age <= 79) { + if(gender !== "undifferentiated") emit(gender + "_70-79", 1); + emit("total_70-79", 1); + } else if(age >= 80 && age <= 89) { + if(gender !== "undifferentiated") emit(gender + "_80-89", 1); + emit("total_80-89", 1); + } else { + if(gender !== "undifferentiated") emit(gender + "_90+", 1); + emit("total_90+", 1); + } + + emit("total_population", 1); +} diff --git a/test/fixtures/pdc/primary_statins_map.js b/test/fixtures/pdc/primary_statins_map.js new file mode 100644 index 0000000..2b582d5 --- /dev/null +++ b/test/fixtures/pdc/primary_statins_map.js @@ -0,0 +1,85 @@ +// Reference Number: PDC-057 +// Query Title: Statins for primary prevention +// TODO: Add freetext definition search +function map(patient) { + var targetProblemCodes = { + "ICD9": ["410..*", "411..*", "412..*", "429.7", "410", "411", "412", + "V17.1", "438", "433.1", "434.1", "438..*"] + }; + + var targetDrugCodes = { + "whoATC": ["C10AA", "C10BX"] + }; + + var drugList = patient.medications(); + var problemList = patient.conditions(); + + var now = new Date(2013, 10, 30); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // a and b are javascript Date objects + // Returns a with the 1.2x calculated date offset added in + function endDateOffset(a, b) { + var start = new Date(a); + var end = new Date(b); + var diff = Math.floor((end-start) / (1000*3600*24)); + var offset = Math.floor(1.2 * diff); + return addDate(start, 0, 0, offset); + } + + function isCurrentDrug(drug) { + var drugStart = drug.indicateMedicationStart().getTime(); + var drugEnd = drug.indicateMedicationStop().getTime(); + + return (endDateOffset(drugStart, drugEnd) >= now && drugStart <= now); + } + + // Checks for diabetic patients + function hasProblemCode() { + return problemList.regex_match(targetProblemCodes).length; + } + + // Checks for active statin prescription + function hasCurrentDrugCode() { + var targetDrugList = targetDrugCodes["whoATC"]; + + for(var i = 0; i < drugList.length; i++) { + // Get all represented codes for each drug + var codes = drugList[i].medicationInformation().codedProduct(); + + // Filter out only ATC codes + for(var j = 0; j < codes.length; j++) { + if(codes[j].codeSystemName().toLowerCase() !== null && + codes[j].codeSystemName().toLowerCase() === "whoATC".toLowerCase()) { + if(targetDrugList.indexOf(codes[j].code().substring(0, 5)) > -1) { + emit("had_statins", 1); + if(isCurrentDrug(drugList[i])) { + return true; + } + } + } + } + } + + return false; + } + + if (hasCurrentDrugCode()) { + emit("denominator_has_current_statin", 1); + if(!hasProblemCode()) { + emit("numerator_no_mi_or_stroke", 1); + } + } + + // Empty Case + emit("numerator_no_mi_or_stroke", 0); + emit("denominator_has_current_statin", 0); +} diff --git a/test/fixtures/pdc/renal_digoxin_value_map.js b/test/fixtures/pdc/renal_digoxin_value_map.js new file mode 100644 index 0000000..10844d5 --- /dev/null +++ b/test/fixtures/pdc/renal_digoxin_value_map.js @@ -0,0 +1,165 @@ +// Reference Number: PDC-056 +// Query Title: Patients, 65 and older, with impaired renal function who are on digoxin >125 mcg/day +function map(patient) { + var targetMedicationCodes = { + "whoATC": ["C01AA*"], + "HC-DIN": ["02281236", "02281228", "02281201", "02245428", "02245427", + "02245426", "02048264", "02048272", "0021415", "00698296", "00647470"] + }; + + var targetCreatinineCodes = { + "pCLOCD": ["45066-8", "14682-9", "2160-0", "33914-3", "50044-7", "48642-3", "48643-1"] + }; + + var targetEGFRCodes = { + "pCLOCD": ["33914-3"] + }; + + var ageLimit = 65; + var creatinineLimit = 150; // Measured in umol/L + var egfrLimit = 50; // Measured in ml/min + var digoxinLimit = 0.125; // Measured in MG + + var drugList = patient.medications(); + var resultList = patient.results(); + + var now = new Date(2013, 10, 30); + var start = new Date(2000, 6, 1); + var end = addDate(now, 0, 1, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // a and b are javascript Date objects + // Returns a with the 1.2x calculated date offset added in + function endDateOffset(a, b) { + var start = new Date(a); + var end = new Date(b); + var diff = Math.floor((end-start) / (1000*3600*24)); + var offset = Math.floor(1.2 * diff); + return addDate(start, 0, 0, offset); + } + + function isCurrentDrug(drug) { + var drugStart = drug.indicateMedicationStart().getTime(); + var drugEnd = drug.indicateMedicationStop().getTime(); + + return (endDateOffset(drugStart, drugEnd) >= now && drugStart <= now); + } + + // Checks if patient is older than ageLimit + function population(patient) { + return (patient.age(now) >= ageLimit); + } + + // Checks for Creatinine labs performed within the last 10 years + function hasCreatinineCode() { + return resultList.match(targetCreatinineCodes, addDate(now, -10, 0, 0), end).length; + } + + // Checks for eGFR labs performed within the last 10 years + function hasEGFRCode() { + return resultList.match(targetEGFRCodes, addDate(now, -10, 0, 0), end).length; + } + + // Checks for existence of Digoxin + function hasMedication() { + return drugList.regex_match(targetMedicationCodes, start, end).length; + } + + // Checks for impaired renal function + function hasImpairedRenalFunctionCode() { + return hasCreatinineCode() || hasEGFRCode(); + } + + // Checks if Creatinine meets parameters + function hasMatchingCreatinineValue() { + for (var i = 0; i < resultList.length; i++) { + if (resultList[i].includesCodeFrom(targetCreatinineCodes) && + resultList[i].timeStamp() > start) { + if (resultList[i].values()[0].units() !== null && + resultList[i].values()[0].units().toLowerCase() === "umol/L".toLowerCase()) { + if (resultList[i].values()[0].scalar() > creatinineLimit) { + return true; + } + } + } + } + return false; + } + + // Checks if eGFR meets parameters + function hasMatchingEGFRValue() { + for (var i = 0; i < resultList.length; i++) { + if (resultList[i].includesCodeFrom(targetEGFRCodes) && + resultList[i].timeStamp() > start) { + if (resultList[i].values()[0].units() !== null && + resultList[i].values()[0].units().toLowerCase() === "mL/min".toLowerCase()) { + if (resultList[i].values()[0].scalar() > egfrLimit) { + return true; + } + } + } + } + return false; + } + + // Checks if Lab values indicate impared renal function + function hasImpairedRenalLabValues() { + return hasMatchingCreatinineValue() || hasMatchingEGFRValue(); + } + + // Checks if existing Digoxin is current + function hasCurrentMedication() { + for (var i = 0; i < drugList.length; i++) { + var tmpArray = new hQuery.CodedEntryList(); + tmpArray[0] = drugList[i]; + if (tmpArray.match(targetMedicationCodes)) { + if(isCurrentDrug(drugList[i])) { + return true; + } + } + } + return false; + } + + // Checks if Digoxin meets dosage parameters + function hasMatchingMedicationDose() { + for (var i = 0; i < drugList.length; i++) { + var codes = drugList[i].medicationInformation().codedProduct(); + + // If Digoxin, check for dose parameter + for (var j = 0; j < codes.length; j++) { + if (codes[j].includedIn(targetMedicationCodes)) { + if (drugList[i].values()[0].units() !== null && + drugList[i].values()[0].units().toLowerCase() === "MG".toLowerCase()) { + if (drugList[i].values()[0].scalar() > digoxinLimit) { + return true; + } + } + } + } + } + return false; + } + + if (population(patient)) { + emit("senior_pop", 1); + if(hasImpairedRenalFunctionCode() && hasImpairedRenalLabValues()) { + emit("denominator_senior_pop_impaired_renal", 1); + if(hasMedication() && hasCurrentMedication() && hasMatchingMedicationDose()) { + emit("numerator_senior_pop_renal_digoxin", 1); + } + } + } + + // Empty Case + emit("numerator_senior_pop_renal_digoxin", 0); + emit("denominator_senior_pop_impaired_renal", 0); +} diff --git a/test/fixtures/pdc/secondary_statins_map.js b/test/fixtures/pdc/secondary_statins_map.js new file mode 100644 index 0000000..dd84dad --- /dev/null +++ b/test/fixtures/pdc/secondary_statins_map.js @@ -0,0 +1,85 @@ +// Reference Number: PDC-058 +// Query Title: Statins for secondary prevention +// TODO: Add freetext definition search +function map(patient) { + var targetProblemCodes = { + "ICD9": ["410..*", "411..*", "412..*", "429.7", "410", "411", "412", + "V17.1", "438", "433.1", "434.1", "438..*"] + }; + + var targetDrugCodes = { + "whoATC": ["C10AA", "C10BX"] + }; + + var drugList = patient.medications(); + var problemList = patient.conditions(); + + var now = new Date(2013, 10, 30); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // a and b are javascript Date objects + // Returns a with the 1.2x calculated date offset added in + function endDateOffset(a, b) { + var start = new Date(a); + var end = new Date(b); + var diff = Math.floor((end-start) / (1000*3600*24)); + var offset = Math.floor(1.2 * diff); + return addDate(start, 0, 0, offset); + } + + function isCurrentDrug(drug) { + var drugStart = drug.indicateMedicationStart().getTime(); + var drugEnd = drug.indicateMedicationStop().getTime(); + + return (endDateOffset(drugStart, drugEnd) >= now && drugStart <= now); + } + + // Checks for diabetic patients + function hasProblemCode() { + return problemList.regex_match(targetProblemCodes).length; + } + + // Checks for active statin prescription + function hasCurrentDrugCode() { + var targetDrugList = targetDrugCodes["whoATC"]; + + for(var i = 0; i < drugList.length; i++) { + // Get all represented codes for each drug + var codes = drugList[i].medicationInformation().codedProduct(); + + // Filter out only ATC codes + for(var j = 0; j < codes.length; j++) { + if(codes[j].codeSystemName().toLowerCase() !== null && + codes[j].codeSystemName().toLowerCase() === "whoATC".toLowerCase()) { + if(targetDrugList.indexOf(codes[j].code().substring(0, 5)) > -1) { + emit("had_statins", 1); + if(isCurrentDrug(drugList[i])) { + return true; + } + } + } + } + } + + return false; + } + + if (hasCurrentDrugCode()) { + emit("denominator_has_current_statin", 1); + if(hasProblemCode()) { + emit("numerator_mi_or_stroke", 1); + } + } + + // Empty Case + emit("numerator_mi_or_stroke", 0); + emit("denominator_has_current_statin", 0); +} diff --git a/test/fixtures/scoop-records.json b/test/fixtures/scoop-records.json new file mode 100644 index 0000000..8dca80f --- /dev/null +++ b/test/fixtures/scoop-records.json @@ -0,0 +1,10 @@ +{ "_id" : "1", "emr_demographics_primary_key" : "1", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "s/Q1SdAMY/S6mlao6erGW8sO1N0Z5XYXsSd2Ug==", "last" : "7ETUHfZcSQduD+JS3qauh9vPmWUp1xbe56I3Bw==", "birthdate" : -923616000, "gender" : "M", "medical_record_number" : "m59ceyj+C/6mnU2V32L/0G5XHZ3folWFlz8NTg==", "languages" : [ "EN" ], "hash_id" : "oqG3YBB7rJvxeUAmPu2Mv2Q/cUji905I9IoJ4w==", "allergies" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000bf" }, "codes" : { "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "_type" : "Allergy", "start_time" : 1362441600, "description" : "PENICILLINS, COMBINATIONS WITH OTHER ANTIBACTERIAL", "status_code" : { "SNOMED-CT" : [ "410605003" ] }, "type" : { "code" : "MED", "displayName" : "Medication", "codeSystem" : "2.16.840.1.113883.5.4", "codeSystemName" : "HL7 ActCode" }, "reaction" : { "text" : "", "value" : null }, "severity" : null } ], "conditions" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000c0" }, "codes" : { "ICD9" : [ "428" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "HEART FAILURE*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000c1" }, "codes" : { "ICD9" : [ "401" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "ESSENTIAL HYPERTENSION*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000c2" }, "codes" : { "ICD9" : [ "250" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "DIABETES MELLITUS*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000c3" }, "codes" : { "ICD9" : [ "491" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "CHRONIC BRONCHITIS*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "encounters" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000c4" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380124200, "description" : "[25-Sep-2013 .: Tel-Progress Notes]\nBP 130/85 sitting position \nHT 187 in cm \nHR 85 in bpm (nnn) Range:40-180 \nTEMP 37 degrees celcius \nWAIS 92 Waist Circum in cm \nWT 95 in kg", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e6b610000c5" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "[25-Sep-2013 .: Tel-Progress Notes]\nBP 130/85 sitting position \nHT 187 in cm \nHR 85 in bpm (nnn) Range:40-180 \nTEMP 37 degrees celcius \nWAIS 92 Waist Circum in cm \nWT 95 in kg", "start_time" : 1380124200 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000c6" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212303, "description" : "Situational Crisis", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e6b610000c7" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Situational Crisis", "start_time" : 1380212303 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000c8" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212341, "description" : "Vitamin D3", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e6b610000c9" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Vitamin D3", "start_time" : 1380212341 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000ca" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212399, "description" : "Vitamin C", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e6b610000cb" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Vitamin C", "start_time" : 1380212399 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000cc" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212410, "description" : "Ginseng Tincture", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e6b610000cd" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Ginseng Tincture", "start_time" : 1380212410 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000ce" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212435, "description" : "Heart Attack", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e6b610000cf" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Heart Attack", "start_time" : 1380212435 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ], "immunizations" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000d0" }, "codes" : { "whoATC" : [ "J07CA01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1346457600, "description" : "Td" }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000d1" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1233446400, "description" : "Flu" }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000d2" }, "codes" : { "whoATC" : [ "J07AL02" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1351641600, "description" : "Pneumovax" } ], "medications" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000d3" }, "codes" : { "HC-DIN" : [ "00559407" ], "whoATC" : [ "N02BE01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 4 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "25 D" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "TYLENOL EXTRA STRENGTH TAB 500MG", "start_time" : 1380240000, "end_time" : 1384560000, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000d4" }, "scalar" : "500.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000d5" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1384560000, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000d6" }, "codes" : { "HC-DIN" : [ "00613215" ], "whoATC" : [ "C03DA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "SPIRONOLACTONE 25MG TABLET", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000d7" }, "scalar" : "25.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000d8" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000d9" }, "codes" : { "HC-DIN" : [ "00636533" ], "whoATC" : [ "M01AE01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 3 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "IBUPROFEN TAB 400MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000da" }, "scalar" : "400.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000db" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000dc" }, "codes" : { "HC-DIN" : [ "02041421" ], "whoATC" : [ "N05BA06" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 2 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "20 D" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "SL", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "SL" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "ATIVAN 1MG", "start_time" : 1380240000, "end_time" : 1383696000, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000dd" }, "scalar" : "1.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000de" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1383696000, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000df" }, "codes" : { "HC-DIN" : [ "02244993" ], "whoATC" : [ "B01AC06" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "ECTAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET (ENTERIC-COATED)" }, "description" : "ASA 81 MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000e0" }, "scalar" : "81.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000e1" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000e2" }, "codes" : { "HC-DIN" : [ "02351420" ], "whoATC" : [ "C03CA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "56 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "FUROSEMIDE 20MG", "start_time" : 1380240000, "end_time" : 1389916800, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000e3" }, "scalar" : "20.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000e4" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1389916800, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000e5" }, "codes" : { "HC-DIN" : [ "02363283" ], "whoATC" : [ "C09AA05" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "AVA-RAMIPRIL 5MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000e6" }, "scalar" : "5.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000e7" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000e8" }, "codes" : { "HC-DIN" : [ "02364948" ], "whoATC" : [ "C07AG02" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "CARVEDILOL 12.5MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000e9" }, "scalar" : "12.5", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000ea" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000eb" }, "codes" : { "HC-DIN" : [ "02387913" ], "whoATC" : [ "C10AA05" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "ATORVASTATIN 40MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000ec" }, "scalar" : "40.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000ed" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] } ], "results" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000ee" }, "codes" : { "pCLOCD" : [ "6690-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "WBC", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 4.0", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000ef" }, "scalar" : "8.0", "units" : "giga/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000f0" }, "codes" : { "pCLOCD" : [ "789-8" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "RBC", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 4.20", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000f1" }, "scalar" : "4.71", "units" : "tera/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000f2" }, "codes" : { "pCLOCD" : [ "718-7" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Hemoglobin", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 133", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000f3" }, "scalar" : "158", "units" : "g/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000f4" }, "codes" : { "pCLOCD" : [ "4544-3" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "free_text" : "0.46", "description" : "Hematocrit", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 0.38" }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000f5" }, "codes" : { "pCLOCD" : [ "787-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "A", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "MCV", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 82", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000f6" }, "scalar" : "99", "units" : "fl", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000f7" }, "codes" : { "pCLOCD" : [ "785-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "MCH", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 27.5", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000f8" }, "scalar" : "33.5", "units" : "pg", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000f9" }, "codes" : { "pCLOCD" : [ "786-4" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "MCHC", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 305", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000fa" }, "scalar" : "341", "units" : "g/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000fb" }, "codes" : { "pCLOCD" : [ "788-0" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "RDW", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 11.5", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000fc" }, "scalar" : "12.6", "units" : "%", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000fd" }, "codes" : { "pCLOCD" : [ "777-3" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Platelet Count", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 150", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b610000fe" }, "scalar" : "295", "units" : "giga/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b610000ff" }, "codes" : { "pCLOCD" : [ "751-8" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Neutrophils", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 2.0", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000100" }, "scalar" : "6.0", "units" : "giga/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000101" }, "codes" : { "pCLOCD" : [ "731-0" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Lymphocytes", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 1.0", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000102" }, "scalar" : "1.6", "units" : "giga/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000103" }, "codes" : { "pCLOCD" : [ "742-7" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Monocytes", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 0.1", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000104" }, "scalar" : "0.4", "units" : "giga/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000105" }, "codes" : { "pCLOCD" : [ "711-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Eosinophils", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 0.0", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000106" }, "scalar" : "0.1", "units" : "giga/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000107" }, "codes" : { "pCLOCD" : [ "704-7" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Basophils", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 0.0", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000108" }, "scalar" : "0.0", "units" : "giga/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000109" }, "codes" : { "pCLOCD" : [ "6301-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "free_text" : "1.0", "description" : "INR", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 0.8" }, { "_id" : { "$oid" : "55e9eb25b4397e6b6100010a" }, "codes" : { "pCLOCD" : [ "14749-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Glucose Random", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 3.3", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b6100010b" }, "scalar" : "5.2", "units" : "mmol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b6100010c" }, "codes" : { "pCLOCD" : [ "14682-9" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "A", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Creatinine", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 70", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b6100010d" }, "scalar" : "68", "units" : "umol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b6100010e" }, "codes" : { "pCLOCD" : [ "33914-3" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Estimated GFR", "status_code" : { "value" : "complete" }, "referenceRange" : ">=60", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b6100010f" }, "scalar" : "113", "units" : "mL/min", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000110" }, "codes" : { "pCLOCD" : [ "14933-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Uric Acid", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 234", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000111" }, "scalar" : "317", "units" : "umol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000112" }, "codes" : { "pCLOCD" : [ "1751-7" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Albumin", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 35", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000113" }, "scalar" : "45", "units" : "g/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000114" }, "codes" : { "pCLOCD" : [ "14631-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Total Bilirubin", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000115" }, "scalar" : "16", "units" : "umol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000116" }, "codes" : { "pCLOCD" : [ "14629-0" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Direct Bilirubin", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000117" }, "scalar" : "5", "units" : "umol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000118" }, "codes" : { "pCLOCD" : [ "6768-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Alkaline Phosphatase", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 48", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000119" }, "scalar" : "74", "units" : "U/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b6100011a" }, "codes" : { "pCLOCD" : [ "2324-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Gamma GT", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 10", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b6100011b" }, "scalar" : "10", "units" : "U/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b6100011c" }, "codes" : { "pCLOCD" : [ "1742-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "ALT", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b6100011d" }, "scalar" : "19", "units" : "U/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b6100011e" }, "codes" : { "pCLOCD" : [ "1920-8" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "AST", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b6100011f" }, "scalar" : "25", "units" : "U/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000120" }, "codes" : { "pCLOCD" : [ "2524-7" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "description" : "Lactic Acid", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 0.7", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000121" }, "scalar" : "1.0", "units" : "mmol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000122" }, "codes" : { "pCLOCD" : [ "46425-5" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "A", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1369995612, "free_text" : "Slight", "description" : "Lipemia", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified" } ], "vital_signs" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000123" }, "codes" : { "LOINC" : [ "8480-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380067200, "description" : "Systolic Blood Pressure (sitting position)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000124" }, "scalar" : "130", "units" : "mm[Hg]", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000125" }, "codes" : { "LOINC" : [ "8462-4" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380067200, "description" : "Diastolic Blood Pressure (sitting position)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000126" }, "scalar" : "85", "units" : "mm[Hg]", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000127" }, "codes" : { "LOINC" : [ "8302-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380067200, "description" : "Height (in cm)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000128" }, "scalar" : "187", "units" : "cm", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b61000129" }, "codes" : { "LOINC" : [ "8867-4" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380067200, "description" : "Heart Rate (in bpm (nnn) Range:40-180)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b6100012a" }, "scalar" : "85", "units" : "beats/min", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b6100012b" }, "codes" : { "LOINC" : [ "8310-5" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380067200, "description" : "Temperature (degrees celcius)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b6100012c" }, "scalar" : "37", "units" : "C", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b6100012d" }, "codes" : { "LOINC" : [ "56115-9" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380067200, "description" : "Waist (Waist Circum in cm)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b6100012e" }, "scalar" : "92", "units" : "cm", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e6b6100012f" }, "codes" : { "LOINC" : [ "3141-9" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380067200, "description" : "Weight (in kg)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e6b61000130" }, "scalar" : "95", "units" : "kg", "_type" : "PhysicalQuantityResultValue" } ] } ] } +{ "_id" : "10", "emr_demographics_primary_key" : "10", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "7J4v3GpycOGNV+vMiYN0TsbmCv9tbSAjXFnidg==", "last" : "actrZ2dUi6AEDxwcG2k9J2YSV15bnoai3L2MeA==", "birthdate" : -627350400, "gender" : "F", "medical_record_number" : "cXla2QS/bfr5B9x4Y9KMGjpLfIXq9uKHHzvJSg==", "languages" : [ "EN" ], "hash_id" : "PsijhUOKd9oeyUKOEbVdP3HeCDqJTjXGM6fk5A==", "conditions" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000a5" }, "codes" : { "ICD9" : [ "250" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "DIABETES MELLITUS*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e0b520000a6" }, "codes" : { "ICD9" : [ "585" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "CHRONIC RENAL FAILURE", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "encounters" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000a7" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380209480, "description" : "[26-Sep-2013 .: Tel-Progress Notes] \n\nBP 130/85 sitting position \nHT 160 in cm \nWT 85 in kg", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e0b520000a8" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "[26-Sep-2013 .: Tel-Progress Notes] \n\nBP 130/85 sitting position \nHT 160 in cm \nWT 85 in kg", "start_time" : 1380209480 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ], "immunizations" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000a9" }, "codes" : { "whoATC" : [ "J07AL02" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1350259200, "description" : "Pneumovax" } ], "medications" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000aa" }, "codes" : { "HC-DIN" : [ "02385341" ], "whoATC" : [ "A10BA02" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 2 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "84 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "METFORMIN FC 500MG", "start_time" : 1380240000, "end_time" : 1387497600, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000ab" }, "scalar" : "500.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000ac" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1387497600, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] } ], "results" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000ad" }, "codes" : { "pCLOCD" : [ "14771-0" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1371734684, "description" : "Glucose Fasting", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 3.6", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000ae" }, "scalar" : "5.1", "units" : "mmol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e0b520000af" }, "codes" : { "pCLOCD" : [ "58453-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1371734684, "description" : "Occult Blood Immunochemical", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000b0" }, "scalar" : "38", "units" : "ng/mL", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e0b520000b1" }, "codes" : { "pCLOCD" : [ "4548-4" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "A", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1371734684, "description" : "Hemoglobin A1c", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 4.8", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000b2" }, "scalar" : "6.1", "units" : "%", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e0b520000b3" }, "codes" : { "pCLOCD" : [ "39469-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1371734684, "description" : "LDL Cholesterol", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000b4" }, "scalar" : "2.9", "units" : "mmol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e0b520000b5" }, "codes" : { "pCLOCD" : [ "1751-7" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1371734684, "description" : "Albumin", "status_code" : { "value" : "complete" }, "referenceRange" : "687", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000b6" }, "scalar" : "45", "units" : "g/L", "_type" : "PhysicalQuantityResultValue" } ] } ], "vital_signs" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000b7" }, "codes" : { "LOINC" : [ "8480-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380153600, "description" : "Systolic Blood Pressure (sitting position)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000b8" }, "scalar" : "130", "units" : "mm[Hg]", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e0b520000b9" }, "codes" : { "LOINC" : [ "8462-4" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380153600, "description" : "Diastolic Blood Pressure (sitting position)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000ba" }, "scalar" : "85", "units" : "mm[Hg]", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e0b520000bb" }, "codes" : { "LOINC" : [ "8302-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380153600, "description" : "Height (in cm)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000bc" }, "scalar" : "160", "units" : "cm", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397e0b520000bd" }, "codes" : { "LOINC" : [ "3141-9" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380153600, "description" : "Weight (in kg)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e0b520000be" }, "scalar" : "85", "units" : "kg", "_type" : "PhysicalQuantityResultValue" } ] } ] } +{ "_id" : "2", "emr_demographics_primary_key" : "2", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "qofQ8hXDWHvCiL9W8zrXt9zjv2U79vAeNF8qDQ==", "last" : "ANKS2Kk+PAz0eBSzU8akswz4oAnRAO3EQ++TLA==", "birthdate" : -818208000, "gender" : "M", "medical_record_number" : "scXmP8VpC1KniVmEVZEYQ+pgXmc0qwQLmXSqSg==", "languages" : [ "EN" ], "hash_id" : "yoixTIpgTHNy1/WjvbgZjo2/ZMrQBYtuCP2Jxg==", "allergies" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000030" }, "codes" : { "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "_type" : "Allergy", "start_time" : 1362441600, "description" : "SULFADIAZINE", "status_code" : { "SNOMED-CT" : [ "410605003" ] }, "type" : { "code" : "MED", "displayName" : "Medication", "codeSystem" : "2.16.840.1.113883.5.4", "codeSystemName" : "HL7 ActCode" }, "reaction" : { "text" : "Hives", "value" : null }, "severity" : { "code" : "A3", "displayName" : "Moderate reaction", "codeSystem" : "2.16.840.1.113883.5.1063", "codeSystemName" : "HL7 ObservationValue" } } ], "conditions" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000031" }, "codes" : { "ICD9" : [ "250" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "DIABETES MELLITUS*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000032" }, "codes" : { "ICD9" : [ "434" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "CEREBRAL ARTERY OCCLUS*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000033" }, "codes" : { "ICD9" : [ "401" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "ESSENTIAL HYPERTENSION*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000034" }, "codes" : { "ICD9" : [ "3000" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "ANXIETY STATES*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "encounters" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000035" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380209371, "description" : "[26-Sep-2013 .: Tel-Progress Notes] \n\nBP 140/90 sitting position", "reason" : { "_id" : { "$oid" : "55e9eb25b4397ebbf3000036" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "[26-Sep-2013 .: Tel-Progress Notes] \n\nBP 140/90 sitting position", "start_time" : 1380209371 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000037" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212501, "description" : "Heart Attack at 50", "reason" : { "_id" : { "$oid" : "55e9eb25b4397ebbf3000038" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Heart Attack at 50", "start_time" : 1380212501 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000039" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212515, "description" : "Vitamin D3", "reason" : { "_id" : { "$oid" : "55e9eb25b4397ebbf300003a" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Vitamin D3", "start_time" : 1380212515 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397ebbf300003b" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212532, "description" : "Adopted - Unknown", "reason" : { "_id" : { "$oid" : "55e9eb25b4397ebbf300003c" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Adopted - Unknown", "start_time" : 1380212532 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ], "immunizations" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300003d" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1351900800, "description" : "Flu" } ], "medications" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300003e" }, "codes" : { "HC-DIN" : [ "00559407" ], "whoATC" : [ "N02BE01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 4 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "25 D" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "TYLENOL EXTRA STRENGTH TAB 500MG", "start_time" : 1380240000, "end_time" : 1384560000, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300003f" }, "scalar" : "500.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000040" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1384560000, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000041" }, "codes" : { "HC-DIN" : [ "00613215" ], "whoATC" : [ "C03DA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "SPIRONOLACTONE 25MG TABLET", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000042" }, "scalar" : "25.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000043" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000044" }, "codes" : { "HC-DIN" : [ "00636533" ], "whoATC" : [ "M01AE01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 3 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "IBUPROFEN TAB 400MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000045" }, "scalar" : "400.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000046" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000047" }, "codes" : { "HC-DIN" : [ "02041421" ], "whoATC" : [ "N05BA06" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 2 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "20 D" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "SL", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "SL" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "ATIVAN 1MG", "start_time" : 1380240000, "end_time" : 1383696000, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000048" }, "scalar" : "1.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000049" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1383696000, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf300004a" }, "codes" : { "HC-DIN" : [ "02244993" ], "whoATC" : [ "B01AC06" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "ECTAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET (ENTERIC-COATED)" }, "description" : "ASA 81 MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300004b" }, "scalar" : "81.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300004c" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf300004d" }, "codes" : { "HC-DIN" : [ "02245428" ], "whoATC" : [ "C01AA05" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "PMS-DIGOXIN 0.25MG", "start_time" : 1380240000, "end_time" : 1382659200, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300004e" }, "scalar" : "0.25", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300004f" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1382659200, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000050" }, "codes" : { "HC-DIN" : [ "02351420" ], "whoATC" : [ "C03CA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "56 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "FUROSEMIDE 20MG", "start_time" : 1380240000, "end_time" : 1389916800, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000051" }, "scalar" : "20.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000052" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1389916800, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000053" }, "codes" : { "HC-DIN" : [ "02363283" ], "whoATC" : [ "C09AA05" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "AVA-RAMIPRIL 5MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000054" }, "scalar" : "5.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000055" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000056" }, "codes" : { "HC-DIN" : [ "02364948" ], "whoATC" : [ "C07AG02" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "CARVEDILOL 12.5MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000057" }, "scalar" : "12.5", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000058" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000059" }, "codes" : { "HC-DIN" : [ "02387913" ], "whoATC" : [ "C10AA05" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "ATORVASTATIN 40MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300005a" }, "scalar" : "40.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300005b" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] } ], "results" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300005c" }, "codes" : { "pCLOCD" : [ "45066-8" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "A", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1370604000, "description" : "Creatinine", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300005d" }, "scalar" : "161.2", "units" : "umol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf300005e" }, "codes" : { "pCLOCD" : [ "33914-3" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1370604000, "description" : "Estimated GFR", "status_code" : { "value" : "complete" }, "referenceRange" : ">=60", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf300005f" }, "scalar" : "113", "units" : "mL/min", "_type" : "PhysicalQuantityResultValue" } ] } ], "vital_signs" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000060" }, "codes" : { "LOINC" : [ "8480-6" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380153600, "description" : "Systolic Blood Pressure (sitting position)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000061" }, "scalar" : "140", "units" : "mm[Hg]", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb25b4397ebbf3000062" }, "codes" : { "LOINC" : [ "8462-4" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : null, "start_time" : 1380153600, "description" : "Diastolic Blood Pressure (sitting position)", "free_text" : "", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397ebbf3000063" }, "scalar" : "90", "units" : "mm[Hg]", "_type" : "PhysicalQuantityResultValue" } ] } ] } +{ "_id" : "3", "emr_demographics_primary_key" : "3", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "qomqUb4F8XLmeb9/3NXWVt9YC0B0LYjres/c7A==", "last" : "KxMLJhEGKhozN1uAU88ePa7AeGE+O1bBbhOuJA==", "birthdate" : -452649600, "gender" : "F", "medical_record_number" : "AVoisL2/7pMGi7gOlWP4dDSHwzwGxdN8C63l6w==", "languages" : [ "EN" ], "hash_id" : "OEG5AnezDBmYjThPfCpdakbvBs27Qx1aRN8plw==", "conditions" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000001" }, "codes" : { "ICD9" : [ "401" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "ESSENTIAL HYPERTENSION*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f000002" }, "codes" : { "ICD9" : [ "250" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "DIABETES MELLITUS*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f000003" }, "codes" : { "ICD9" : [ "412" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "OLD MYOCARDIAL INFARCT", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f000004" }, "codes" : { "ICD9" : [ "733" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "OTH BONE AND CARTILAGE DIS*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "encounters" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000005" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212575, "description" : "Calcium and Magnesium", "reason" : { "_id" : { "$oid" : "55e9eb24b4397e969f000006" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Calcium and Magnesium", "start_time" : 1380212575 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb24b4397e969f000007" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212582, "description" : "Vit D3", "reason" : { "_id" : { "$oid" : "55e9eb24b4397e969f000008" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Vit D3", "start_time" : 1380212582 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb24b4397e969f000009" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212592, "description" : "Fish oil - omegas", "reason" : { "_id" : { "$oid" : "55e9eb24b4397e969f00000a" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Fish oil - omegas", "start_time" : 1380212592 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb24b4397e969f00000b" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212618, "description" : "Rheumatoid Arthritis", "reason" : { "_id" : { "$oid" : "55e9eb24b4397e969f00000c" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Rheumatoid Arthritis", "start_time" : 1380212618 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb24b4397e969f00000d" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212634, "description" : "Rheumatoid Arthritis", "reason" : { "_id" : { "$oid" : "55e9eb24b4397e969f00000e" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Rheumatoid Arthritis", "start_time" : 1380212634 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ], "immunizations" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f00000f" }, "codes" : { "whoATC" : [ "J07AL02" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1044057600, "description" : "Pneumovax" }, { "_id" : { "$oid" : "55e9eb24b4397e969f000010" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1351641600, "description" : "Flu" }, { "_id" : { "$oid" : "55e9eb24b4397e969f000011" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1320883200, "description" : "Flu" }, { "_id" : { "$oid" : "55e9eb24b4397e969f000012" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1288310400, "description" : "Flu" } ], "medications" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000013" }, "codes" : { "HC-DIN" : [ "00559407" ], "whoATC" : [ "N02BE01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 4 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "25 D" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "TYLENOL EXTRA STRENGTH TAB 500MG", "start_time" : 1380240000, "end_time" : 1384560000, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000014" }, "scalar" : "500.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000015" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1384560000, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f000016" }, "codes" : { "HC-DIN" : [ "00613215" ], "whoATC" : [ "C03DA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "SPIRONOLACTONE 25MG TABLET", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000017" }, "scalar" : "25.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000018" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f000019" }, "codes" : { "HC-DIN" : [ "02244993" ], "whoATC" : [ "B01AC06" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "ECTAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET (ENTERIC-COATED)" }, "description" : "ASA 81 MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f00001a" }, "scalar" : "81.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f00001b" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f00001c" }, "codes" : { "HC-DIN" : [ "02351420" ], "whoATC" : [ "C03CA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "56 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "FUROSEMIDE 20MG", "start_time" : 1380240000, "end_time" : 1389916800, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f00001d" }, "scalar" : "20.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f00001e" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1389916800, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f00001f" }, "codes" : { "HC-DIN" : [ "02363283" ], "whoATC" : [ "C09AA05" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "AVA-RAMIPRIL 5MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000020" }, "scalar" : "5.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000021" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f000022" }, "codes" : { "HC-DIN" : [ "02364948" ], "whoATC" : [ "C07AG02" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "CARVEDILOL 12.5MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000023" }, "scalar" : "12.5", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000024" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f000025" }, "codes" : { "HC-DIN" : [ "02387913" ], "whoATC" : [ "C10AA05" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "ATORVASTATIN 40MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000026" }, "scalar" : "40.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000027" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] } ], "results" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000028" }, "codes" : { "pCLOCD" : [ "14771-0" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1371734684, "description" : "Glucose Fasting", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 3.6", "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f000029" }, "scalar" : "4.9", "units" : "mmol/L", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f00002a" }, "codes" : { "pCLOCD" : [ "58453-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1371734684, "description" : "Occult Blood Immunochemical", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f00002b" }, "scalar" : "35", "units" : "ng/mL", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f00002c" }, "codes" : { "pCLOCD" : [ "4548-4" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "A", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1371734684, "description" : "Hemoglobin A1c", "status_code" : { "value" : "complete" }, "referenceRange" : "Normal Reference range is greater than 4.8", "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f00002d" }, "scalar" : "6.4", "units" : "%", "_type" : "PhysicalQuantityResultValue" } ] }, { "_id" : { "$oid" : "55e9eb24b4397e969f00002e" }, "codes" : { "pCLOCD" : [ "39469-2" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1371734684, "description" : "LDL Cholesterol", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb24b4397e969f00002f" }, "scalar" : "2.4", "units" : "mmol/L", "_type" : "PhysicalQuantityResultValue" } ] } ] } +{ "_id" : "4", "emr_demographics_primary_key" : "4", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "1PuZ2n72p1kRNKqJjH+aDUh4VD+UQ3HdTuZNsw==", "last" : "lBbh839iF8dZpGYbfhNpZPgLnnHFui7cmkwy0g==", "birthdate" : -1060300800, "gender" : "M", "medical_record_number" : "uGiGzvhpV6QxIJRzBCfd/KRekrZDsX0n2+WkqA==", "languages" : [ "EN" ], "hash_id" : "bAMeRIkXZ88tNy+/NuGaAOLaDrAgLMZFH827Mw==", "conditions" : [ { "_id" : { "$oid" : "55e9eb25b4397ed825000064" }, "codes" : { "ICD9" : [ "7153" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "LOCAL OSTEOARTHROSIS NOS*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "encounters" : [ { "_id" : { "$oid" : "55e9eb25b4397ed825000065" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212655, "description" : "Multivitamin", "reason" : { "_id" : { "$oid" : "55e9eb25b4397ed825000066" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Multivitamin", "start_time" : 1380212655 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397ed825000067" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212677, "description" : "Shark cartiledge", "reason" : { "_id" : { "$oid" : "55e9eb25b4397ed825000068" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Shark cartiledge", "start_time" : 1380212677 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ], "immunizations" : [ { "_id" : { "$oid" : "55e9eb25b4397ed825000069" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1351123200, "description" : "Flu" }, { "_id" : { "$oid" : "55e9eb25b4397ed82500006a" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1321142400, "description" : "Flu" }, { "_id" : { "$oid" : "55e9eb25b4397ed82500006b" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1130544000, "description" : "Flu" } ] } +{ "_id" : "5", "emr_demographics_primary_key" : "5", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "D20TbB1L/DgMJ60TM1p+dtyRrY7PVO+Eznnwmg==", "last" : "He0TjGb3FFfZG7+5XuTR3YNYZTgmWO3kQDU5QQ==", "birthdate" : 97113600, "gender" : "F", "medical_record_number" : "VBG+M1Lnwo1zVFd7podU6yZBst03qDv46nM/VA==", "languages" : [ "EN" ], "hash_id" : "DCaNi3yVky+ZGoMFoktPerDF1wLY88//9n3EBA==", "allergies" : [ { "_id" : { "$oid" : "55e9eb25b4397e4308000097" }, "codes" : { "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "_type" : "Allergy", "start_time" : 1362441600, "description" : "PEANUT OIL", "status_code" : { "SNOMED-CT" : [ "410605003" ] }, "type" : { "code" : "MED", "displayName" : "Medication", "codeSystem" : "2.16.840.1.113883.5.4", "codeSystemName" : "HL7 ActCode" }, "reaction" : { "text" : "anaphylaxis", "value" : null }, "severity" : { "code" : "A4", "displayName" : "Severe reaction", "codeSystem" : "2.16.840.1.113883.5.1063", "codeSystemName" : "HL7 ObservationValue" } } ], "conditions" : [ { "_id" : { "$oid" : "55e9eb25b4397e4308000098" }, "codes" : { "ICD9" : [ "244" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "ACQUIRED HYPOTHYROIDISM*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "encounters" : [ { "_id" : { "$oid" : "55e9eb25b4397e4308000099" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212708, "description" : "Vit D", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e430800009a" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Vit D", "start_time" : 1380212708 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e430800009b" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212717, "description" : "Ibuprofen as needed", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e430800009c" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Ibuprofen as needed", "start_time" : 1380212717 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ], "medications" : [ { "_id" : { "$oid" : "55e9eb25b4397e430800009d" }, "codes" : { "HC-DIN" : [ "00509558" ], "whoATC" : [ "C01CA24" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : null, "denominator" : null } }, "freeTextSig" : " E2E_PRN_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "completed" }, "longTerm" : false, "route" : { "code" : "IM", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "IM" }, "productForm" : { "code" : "SOL", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "SOLUTION" }, "description" : "EPIPEN 0.3MG/0.3ML AUTO-INJECTOR", "start_time" : 1380240000, "end_time" : 1380240000, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e430800009e" }, "scalar" : "1.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e430800009f" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1380240000, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e43080000a0" }, "codes" : { "HC-DIN" : [ "02172100" ], "whoATC" : [ "H03AA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "112 D" }, "freeTextSig" : "", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "completed" }, "longTerm" : false, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "SYNTHROID - TAB 100MCG", "start_time" : 1380240000, "end_time" : 1389916800, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e43080000a1" }, "scalar" : "100.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e43080000a2" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1389916800, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] } ], "results" : [ { "_id" : { "$oid" : "55e9eb25b4397e43080000a3" }, "codes" : { "pCLOCD" : [ "45066-8" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "N", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1370604000, "description" : "Creatinine", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e43080000a4" }, "scalar" : "131.6", "units" : "umol/L", "_type" : "PhysicalQuantityResultValue" } ] } ] } +{ "_id" : "6", "emr_demographics_primary_key" : "6", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "oBQJqCva29WPkn3zjmSYHbrm6Ad4Swj/7IGu5A==", "last" : "lk1azu0vDbxSTpS/4RWsKvk9W4vh52+4g9oEmg==", "birthdate" : -1591315200, "gender" : "M", "medical_record_number" : "x0EcRSoFvcFjoyDqJOH0jPoCQ4NXjfkBWn6ilg==", "languages" : [ "EN" ], "hash_id" : "3oTex5Pgs2pVwYYcChbrNwmH6qngilYeDYvrpw==", "conditions" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd00006c" }, "codes" : { "ICD9" : [ "492" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "EMPHYSEMA*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd00006d" }, "codes" : { "ICD9" : [ "8054" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "FX LUMBAR VERTEBRA-CLOSE", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd00006e" }, "codes" : { "ICD9" : [ "272" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "DIS OF LIPOID METABOLISM*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd00006f" }, "codes" : { "ICD9" : [ "410" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "ACUTE MYOCARDIAL INFARCT*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "immunizations" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000070" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1351123200, "description" : "Flu" } ], "medications" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000071" }, "codes" : { "HC-DIN" : [ "00559407" ], "whoATC" : [ "N02BE01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "h", "value" : 6 } }, "text" : "25 D" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "TYLENOL EXTRA STRENGTH TAB 500MG", "start_time" : 1380240000, "end_time" : 1384560000, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000072" }, "scalar" : "500.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000073" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1384560000, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd000074" }, "codes" : { "HC-DIN" : [ "02014203" ], "whoATC" : [ "N02AA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "h", "value" : 4 } }, "text" : "16 D" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "MS IR TAB 5MG", "start_time" : 1380240000, "end_time" : 1383004800, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000075" }, "scalar" : "5.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000076" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1383004800, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd000077" }, "codes" : { "HC-DIN" : [ "02014319" ], "whoATC" : [ "N02AA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "h", "value" : 12 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "ERTAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET (EXTENDED-RELEASE)" }, "description" : "MS CONTIN SRT 100MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000078" }, "scalar" : "100.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000079" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd00007a" }, "codes" : { "HC-DIN" : [ "02241497" ], "whoATC" : [ "R03AC02" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 2 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "4 W" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "INH", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "INH" }, "productForm" : { "code" : "MDINHL", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "METERED-DOSE AEROSOL" }, "description" : "VENTOLIN HFA 100?G", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd00007b" }, "scalar" : "100.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd00007c" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd00007d" }, "codes" : { "HC-DIN" : [ "02242030" ], "whoATC" : [ "R03BA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 2 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "4 W" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "2.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "INH", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "INH" }, "productForm" : { "code" : "MDINHL", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "METERED-DOSE AEROSOL" }, "description" : "QVAR 100?G", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd00007e" }, "scalar" : "100.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd00007f" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd000080" }, "codes" : { "HC-DIN" : [ "02244993" ], "whoATC" : [ "B01AC06" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "ECTAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET (ENTERIC-COATED)" }, "description" : "ASA 81 MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000081" }, "scalar" : "81.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000082" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd000083" }, "codes" : { "HC-DIN" : [ "02247686" ], "whoATC" : [ "R03BB01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 3 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "4 W" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "INH", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "INH" }, "productForm" : { "code" : "MDINHL", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "METERED-DOSE AEROSOL" }, "description" : "ATROVENT HFA 20?G", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000084" }, "scalar" : "20.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000085" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd000086" }, "codes" : { "HC-DIN" : [ "02344157" ], "whoATC" : [ "N06AB03" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "CAP", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "CAPSULE" }, "description" : "FLUOXETINE 20MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000087" }, "scalar" : "20.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd000088" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e06fd000089" }, "codes" : { "HC-DIN" : [ "02387913" ], "whoATC" : [ "C10AA05" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "ATORVASTATIN 40MG", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd00008a" }, "scalar" : "40.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e06fd00008b" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] } ] } +{ "_id" : "7", "emr_demographics_primary_key" : "7", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "7J4v3GpycOGNV+vMiYN0TsbmCv9tbSAjXFnidg==", "last" : "lk1azu0vDbxSTpS/4RWsKvk9W4vh52+4g9oEmg==", "birthdate" : -1458345600, "gender" : "F", "medical_record_number" : "tmHosMoGelX0ObIe1BZDxB0Je4qWE44/rrgeXw==", "languages" : [ "EN" ], "hash_id" : "Kps1gOhVxhGFPT3a9SaVS4xnyHQiuqgPS56Pvw==", "conditions" : [ { "_id" : { "$oid" : "55e9eb25b4397e85d5000131" }, "codes" : { "ICD9" : [ "492" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "EMPHYSEMA*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "encounters" : [ { "_id" : { "$oid" : "55e9eb25b4397e85d5000132" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212759, "description" : "Post partum depression", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e85d5000133" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Post partum depression", "start_time" : 1380212759 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e85d5000134" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212770, "description" : "Multivit", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e85d5000135" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Multivit", "start_time" : 1380212770 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e85d5000136" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212788, "description" : "Depression", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e85d5000137" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Depression", "start_time" : 1380212788 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e85d5000138" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212800, "description" : "Alcohol Abuse", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e85d5000139" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Alcohol Abuse", "start_time" : 1380212800 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e85d500013a" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212818, "description" : "Alcohol Abuse", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e85d500013b" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "Alcohol Abuse", "start_time" : 1380212818 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ], "immunizations" : [ { "_id" : { "$oid" : "55e9eb25b4397e85d500013c" }, "codes" : { "whoATC" : [ "J07BB01" ] }, "mood_code" : "EVN", "_type" : "Immunization", "start_time" : 1351123200, "description" : "Flu" } ], "medications" : [ { "_id" : { "$oid" : "55e9eb25b4397e85d500013d" }, "codes" : { "HC-DIN" : [ "02241497" ], "whoATC" : [ "R03AC02" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 2 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "4 W" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "2.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "INH", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "INH" }, "productForm" : { "code" : "MDINHL", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "METERED-DOSE AEROSOL" }, "description" : "VENTOLIN HFA 100?G", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e85d500013e" }, "scalar" : "100.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e85d500013f" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e85d5000140" }, "codes" : { "HC-DIN" : [ "02247686" ], "whoATC" : [ "R03BB01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 3 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "4 W" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "2.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "INH", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "INH" }, "productForm" : { "code" : "MDINHL", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "METERED-DOSE AEROSOL" }, "description" : "ATROVENT HFA 20?G", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e85d5000141" }, "scalar" : "20.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e85d5000142" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] } ] } +{ "_id" : "8", "emr_demographics_primary_key" : "8", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "CcR+wS8MFwGhkV8871iRLTQl4O3vmqm6kaYNlg==", "last" : "ZOM63svyU135TAwZHUzUAOzAZedLTyAKqSoKtQ==", "birthdate" : -1441497600, "gender" : "F", "medical_record_number" : "DY2ntNFpBdOHFYAJDJvR/zkLyAKTynZBLxSIUQ==", "languages" : [ "EN" ], "hash_id" : "k+sWIPuFeRxJKh4ZfMoP17O01mh/yVIFQnGQQw==", "conditions" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b0000143" }, "codes" : { "ICD9" : [ "244" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "ACQUIRED HYPOTHYROIDISM*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e03b0000144" }, "codes" : { "ICD9" : [ "3000" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "ANXIETY STATES*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "encounters" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b0000145" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212841, "description" : "tiger balm on hands", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e03b0000146" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "tiger balm on hands", "start_time" : 1380212841 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e03b0000147" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212858, "description" : "anxiety", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e03b0000148" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "anxiety", "start_time" : 1380212858 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } }, { "_id" : { "$oid" : "55e9eb25b4397e03b0000149" }, "codes" : { "code" : [ "REASON" ], "codeSystem" : [ "ObservationType-CA-Pending" ] }, "mood_code" : "EVN", "_type" : "Encounter", "start_time" : 1380212867, "description" : "anxiety", "reason" : { "_id" : { "$oid" : "55e9eb25b4397e03b000014a" }, "codes" : { "ObservationType-CA-Pending" : [ "REASON" ], "Unknown" : [ "NI" ] }, "mood_code" : "EVN", "description" : "anxiety", "start_time" : 1380212867 }, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ], "medications" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b000014b" }, "codes" : { "HC-DIN" : [ "00013285" ], "whoATC" : [ "N05BA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "56 D" }, "freeTextSig" : "", "dose" : { "low" : "2.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "completed" }, "longTerm" : false, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "VALIUM 5 TAB", "start_time" : 1380240000, "end_time" : 1394755200, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b000014c" }, "scalar" : "5.0", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b000014d" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1394755200, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e03b000014e" }, "codes" : { "HC-DIN" : [ "02171228" ], "whoATC" : [ "H03AA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "56 D" }, "freeTextSig" : "", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "completed" }, "longTerm" : false, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "SYNTHROID - TAB 112MCG", "start_time" : 1380240000, "end_time" : 1394755200, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b000014f" }, "scalar" : "112.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b0000150" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1394755200, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e03b0000151" }, "codes" : { "HC-DIN" : [ "02245428" ], "whoATC" : [ "C01AA05" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 1 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "28 D" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "PO", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "PO" }, "productForm" : { "code" : "TAB", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "TABLET" }, "description" : "PMS-DIGOXIN 0.25MG", "start_time" : 1380240000, "end_time" : 1382659200, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b0000152" }, "scalar" : "0.25", "units" : "MG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b0000153" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1382659200, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] } ], "results" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b0000154" }, "codes" : { "pCLOCD" : [ "45066-8" ] }, "mood_code" : "EVN", "_type" : "LabResult", "interpretation" : { "code" : "A", "codeSystem" : "ObservationInterpretation" }, "start_time" : 1370604000, "description" : "Creatinine", "status_code" : { "value" : "complete" }, "referenceRange" : "unspecified", "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e03b0000155" }, "scalar" : "158.4", "units" : "umol/L", "_type" : "PhysicalQuantityResultValue" } ] } ] } +{ "_id" : "9", "emr_demographics_primary_key" : "9", "primary_care_provider_id" : "cpsid", "effective_time" : 1410533220, "first" : "4AeX6o/s/m3xpm3Pw2DWLS0Q+gmHSz57WJBU1g==", "last" : "FUNf8CEQQn0XN1nAsvSnqk2q7D72sjHBSdWtwA==", "birthdate" : -841968000, "gender" : "F", "medical_record_number" : "2pjlPUhoLSd1M8GF1HDWWIqbx1ujVlb9yc1p2Q==", "languages" : [ "EN" ], "hash_id" : "NRvT2crIZ3v/6fVYQsrUYvlKkmhGLwDzIxZo/w==", "conditions" : [ { "_id" : { "$oid" : "55e9eb25b4397e080c00008c" }, "codes" : { "ICD9" : [ "3051" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "TOBACCO USE DISORDER", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e080c00008d" }, "codes" : { "ICD9" : [ "303" ] }, "mood_code" : "EVN", "_type" : "Condition", "description" : "ALCOHOL DEPENDENCE SYNDR*", "type" : null, "start_time" : 1380153600, "status_code" : { "SNOMED-CT" : [ "55561003" ], "HL7 ActStatus" : [ "active" ] }, "time" : null, "treating_provider" : [ { "_id" : { "$oid" : "55e8d588b4397e1e7a000003" }, "title" : "", "given_name" : "", "family_name" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "specialty" : "", "npi" : "0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==", "start" : null, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d588b4397e1e7a000004" } } } ] } ], "medications" : [ { "_id" : { "$oid" : "55e9eb25b4397e080c00008e" }, "codes" : { "HC-DIN" : [ "02241497" ], "whoATC" : [ "R03AC02" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 2 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "4 W" }, "freeTextSig" : " E2E_PRN_FLAG E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "INH", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "INH" }, "productForm" : { "code" : "MDINHL", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "METERED-DOSE AEROSOL" }, "description" : "VENTOLIN HFA 100?G", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e080c00008f" }, "scalar" : "100.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e080c000090" }, "prn" : true, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e080c000091" }, "codes" : { "HC-DIN" : [ "02242030" ], "whoATC" : [ "R03BA01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 2 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "4 W" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "2.0", "high" : "2.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "INH", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "INH" }, "productForm" : { "code" : "MDINHL", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "METERED-DOSE AEROSOL" }, "description" : "QVAR 100?G", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e080c000092" }, "scalar" : "100.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e080c000093" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] }, { "_id" : { "$oid" : "55e9eb25b4397e080c000094" }, "codes" : { "HC-DIN" : [ "02247686" ], "whoATC" : [ "R03BB01" ] }, "mood_code" : "EVN", "_type" : "Medication", "administrationTiming" : { "frequency" : { "numerator" : { "unit" : null, "value" : 3 }, "denominator" : { "unit" : "d", "value" : 1 } }, "text" : "4 W" }, "freeTextSig" : " E2E_LONG_TERM_FLAG", "dose" : { "low" : "1.0", "high" : "1.0" }, "statusOfMedication" : { "value" : "active" }, "longTerm" : true, "route" : { "code" : "INH", "codeSystem" : "2.16.840.1.113883.5.112", "codeSystemName" : "RouteOfAdministration", "displayName" : "INH" }, "productForm" : { "code" : "MDINHL", "codeSystem" : "2.16.840.1.113883.1.11.14570", "displayName" : "METERED-DOSE AEROSOL" }, "description" : "ATROVENT HFA 20?G", "start_time" : 1380240000, "end_time" : 1385078400, "time" : 1380240000, "values" : [ { "_id" : { "$oid" : "55e9eb25b4397e080c000095" }, "scalar" : "20.0", "units" : "µG", "_type" : "PhysicalQuantityResultValue" } ], "orderInformation" : [ { "_id" : { "$oid" : "55e9eb25b4397e080c000096" }, "prn" : false, "orderDateTime" : 1380240000, "orderExpirationDateTime" : 1385078400, "performer" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000001" }, "title" : "", "given_name" : "", "family_name" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "specialty" : "", "npi" : "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", "start" : 1380212575, "end" : null, "organization" : { "_id" : { "$oid" : "55e8d587b4397e1e7a000002" } } } } ] } ] } diff --git a/test/fixtures/scoop/age_gender_map.js b/test/fixtures/scoop/age_gender_map.js new file mode 100644 index 0000000..2386124 --- /dev/null +++ b/test/fixtures/scoop/age_gender_map.js @@ -0,0 +1,12 @@ +function map(patient) { + var time = new Date(2013, 5, 1); + if (patient.gender() == "M") { + var age = patient.age(time); + if (typeof age !== 'undefined') { + age = Math.floor(age); + } + if(age >= 65) { + emit("male_>65", 1); + } + } +} diff --git a/test/fixtures/scoop/codes_with_regex_map.js b/test/fixtures/scoop/codes_with_regex_map.js new file mode 100644 index 0000000..0dc31aa --- /dev/null +++ b/test/fixtures/scoop/codes_with_regex_map.js @@ -0,0 +1,127 @@ +// Illustrates how to specify target codes containing regular expressions +// The match() and includesCodeFrom() methods need to be replaced with +// regex_match() and regex_includesCodeFrom() + +function map(patient) { + //"LOINC": ["56115-9"] + var targetWaistCircumferenceCodes = { + "LOINC": ["56115.*"] + }; + + //"LOINC": ['8302-2'] + var targetHeightCodes = { + "LOINC": ['8302-.'] + } + + // "LOINC": ["3141-9"] + var targetWeightCodes = { + "LOINC": ["3141.."] + } + + var ageLimit = 19; + + var wcLimit = 90; // waist circumference threshold (cm) + + var vitalSignList = patient.vitalSigns(); + + var now = new Date(2013, 10, 30); + var start = addDate(now, -2, 0, 0); + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks if patient is older than ageLimit + function population(patient) { + return (patient.age(now) > ageLimit); + } + + + // Checks for existence of waist circumference observation + function hasWaistCircumference() { + return vitalSignList.regex_match(targetWaistCircumferenceCodes, start, end).length; + } + + function hasHeight() { + return vitalSignList.regex_match(targetHeightCodes, start, end).length; + } + + function hasWeight() { + return vitalSignList.regex_match(targetWeightCodes, start, end).length; + } + + // http://en.wikipedia.org/wiki/Body_mass_index + function calculateBMI(height, weight, metric) { + if (metric) { + bmi = weight/(height/100.0)^2; // assume cm and kg + } else { + bmi = 703 * weight /height^2; // assume in and lb + } + return bmi; + } + + function hasWaistCircumferenceIndicator() { + for (var i = 0; i < vitalSignList.length; i++) { + //if (vitalSignList[i].values()[0].units() == "cm") { + if (vitalSignList[i].regex_includesCodeFrom(targetWaistCircumferenceCodes) && + vitalSignList[i].values()[0].scalar() > wcLimit) { + return true; + } + //} + } + return false; + } + + if (hasHeight()) { + emit("hasHeight", 1); + } else { + emit("hasHeight", 0); + } + + function hasHeightWeightIndicators() { + var height = 0; + var weight = 0; + var bmi = 0; + for (var i = 0; i < vitalSignList.length; i++) { + //if (vitalSignList[i].values()[0].units() == "cm") { + if (vitalSignList[i].regex_includesCodeFrom(targetHeightCodes)) { + height = vitalSignList[i].values()[0].scalar(); + //emit("height="+height,1); + } + if (vitalSignList[i].regex_includesCodeFrom(targetWeightCodes)) { + weight = vitalSignList[i].values()[0].scalar(); + //emit("weight="+weight,1); + } + if (height != 0 && weight != 0) { + bmi = calculateBMI(height,weight,true); + //emit("bmi="+bmi,1); + return bmi > 30; + } + //} + } + return false; + } + + emit('total_pop', 1); + + if (population(patient)) { + //emit("senior_pop: " + patient.given() + " " + patient.last(), 1); + emit(">19_pop", 1); + if (hasWaistCircumference() && hasWaistCircumferenceIndicator()) { + emit(">19_pop_overweight_wc", 1); + } else { + emit(">19_pop_overweight_wc", 0) + }; + if (hasHeightWeightIndicators()) { + emit(">19_pop_bmi>30",1); + } else { + emit(">19_pop_bmi>30",0); + }; + } +} \ No newline at end of file diff --git a/test/fixtures/scoop/graphical_builder_demographics_map.js b/test/fixtures/scoop/graphical_builder_demographics_map.js new file mode 100644 index 0000000..d1ac2ae --- /dev/null +++ b/test/fixtures/scoop/graphical_builder_demographics_map.js @@ -0,0 +1,579 @@ +function map(patient) { + var populationValue = new reducer.Value({ 'target_pop': 0, 'filtered_pop': 0, 'unfound_pop': 0, 'total_pop': 1 }, rereduced = false); + if (find(patient)) { + populationValue.values.filtered_pop = 1; + if (filter(patient)) { + populationValue.values.target_pop = 1; + extract(patient); + } + } else { + populationValue.values.unfound_pop = 1; + } + emit({ 'type': 'population' }, populationValue); +} +function find(patient) { + var root = new queryStructure.And(null, [ new queryStructure.And('demographics', [ new queryStructure.DemographicRule({"ageRange": {"low": 10, "high": 99}, "gender": "M", "raceCode": null, "maritalStatusCode": null}) ]) ]) + return root.test(patient); +} +function filter(patient) { + var root = new queryStructure.And(null, [ ]) + return root.test(patient); +} +function extract(patient) { + var key = { 'type': 'group' }; + var value = new reducer.Value({ }, rereduced = false); + emit(key, value); +} +var queryStructure = queryStructure || {}; +var __hasProp = Object.prototype.hasOwnProperty, __extends = function (child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; +}; + +this.queryStructure || (this.queryStructure = {}); +queryStructure.Query = (function () { + function Query() { + this.find = new queryStructure.And(null); + this.filter = new queryStructure.And(null); + this.extract = new queryStructure.Extraction([], []); + } + + Query.prototype.toJson = function () { + return { 'find': this.find.toJson(), 'filter': this.filter.toJson(), 'extract': this.extract.toJson() }; + }; + Query.prototype.rebuildFromJson = function (json) { + this.find = json['find'] ? this.buildFromJson(null, json['find']) : new queryStructure.And(null); + this.filter = json['filter'] ? this.buildFromJson(null, json['filter']) : new queryStructure.And(null); + return this.extract = json['extract'] ? queryStructure.Extraction.rebuildFromJson(json['extract']) : new queryStructure.Extraction([], []); + }; + Query.prototype.buildFromJson = function (parent, element) { + var child, container, newContainer, ruleType, _i, _len, _ref; + if (this.getElementType(element) === 'rule') { + ruleType = element.type; + return new queryStructure[ruleType](element.data); + } else { + container = this.getContainerType(element); + newContainer = new queryStructure[container](parent, [], element.name, element.title, element.negate); + _ref = element[container.toLowerCase()]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + newContainer.add(this.buildFromJson(newContainer, child)); + } + return newContainer; + } + }; + Query.prototype.getElementType = function (element) { + if ((element['and'] != null) || (element['or'] != null)) { + return 'container'; + } else { + return 'rule'; + } + }; + Query.prototype.getContainerType = function (element) { + if (element['and'] != null) { + return 'And'; + } else if (element['or'] != null) { + return 'Or'; + } else { + return null; + } + }; + return Query; +})(); +queryStructure.Container = (function () { + function Container(parent, children, name, title, negate) { + this.parent = parent; + this.children = children != null ? children : []; + this.name = name; + this.title = title; + this.negate = negate != null ? negate : false; + this.children || (this.children = []); + } + + Container.prototype.add = function (element, after) { + var ci, index; + index = this.children.length; + ci = this.childIndex(after); + if (ci !== -1) index = ci + 1; + this.children.splice(index, 0, element); + if (element.parent && element.parent !== this) { + element.parent.removeChild(element); + } + element.parent = this; + return element; + }; + Container.prototype.addAll = function (items, after) { + var item, _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + _results.push(after = this.add(item, after)); + } + return _results; + }; + Container.prototype.remove = function () { + if (this.parent) return this.parent.removeChild(this); + }; + Container.prototype.removeChild = function (victim) { + var index; + index = this.childIndex(victim); + if (index !== -1) { + this.children.splice(index, 1); + return victim.parent = null; + } + }; + Container.prototype.replaceChild = function (child, newChild) { + var index; + index = this.childIndex(child); + if (index !== -1) { + this.children[index] = newChild; + child.parent = null; + return newChild.parent = this; + } + }; + Container.prototype.moveBefore = function (child, other) { + var i1, i2; + i1 = this.childIndex(child); + i2 = this.childIndex(other); + if (i1 !== -1 && i2 !== -1) { + child = this.children.splice(i2, 1); + this.children.splice(i1 - 1, 0, other); + return true; + } + return false; + }; + Container.prototype.childIndex = function (child) { + var index, _child, _ref; + if (child === null) return -1; + _ref = this.children; + for (index in _ref) { + _child = _ref[index]; + if (_child === child) return index; + } + return -1; + }; + Container.prototype.clear = function () { + return this.children = []; + }; + Container.prototype.childrenToJson = function () { + var child, childJson, js, _i, _len, _ref; + childJson = []; + _ref = this.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + js = child["toJson"] ? child.toJson() : child; + childJson.push(js); + } + return childJson; + }; + return Container; +})(); +queryStructure.Or = (function () { + __extends(Or, queryStructure.Container); + function Or() { + Or.__super__.constructor.apply(this, arguments); + } + + Or.prototype.toJson = function () { + var childJson; + childJson = this.childrenToJson(); + return { "name": this.name, "or": childJson, "negate": this.negate, "title": this.title }; + }; + Or.prototype.test = function (patient) { + var child, retval, _i, _len, _ref; + if (this.children.length === 0) return true; + retval = false; + _ref = this.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (child.test(patient)) { + retval = true; + break; + } + } + if (this.negate) { + return !retval; + } else { + return retval; + } + }; + return Or; +})(); +queryStructure.And = (function () { + __extends(And, queryStructure.Container); + function And() { + And.__super__.constructor.apply(this, arguments); + } + + And.prototype.toJson = function () { + var childJson; + childJson = this.childrenToJson(); + return { "name": this.name, "and": childJson, "negate": this.negate, "title": this.title }; + }; + And.prototype.test = function (patient) { + var child, retval, _i, _len, _ref; + if (this.children.length === 0) return true; + retval = true; + _ref = this.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (!child.test(patient)) { + retval = false; + break; + } + } + if (this.negate) { + return !retval; + } else { + return retval; + } + }; + return And; +})(); +queryStructure.Field = (function () { + function Field(title, callstack) { + this.title = title; + this.callstack = callstack; + } + + Field.prototype.toJson = function () { + return { "title": this.title, "callstack": this.callstack }; + }; + Field.prototype.extract = function (patient) { + return patient[callstack](); + }; + return Field; +})(); +queryStructure.Group = (function () { + __extends(Group, queryStructure.Field); + function Group(title, callstack) { + this.title = title; + this.callstack = callstack; + } + + Group.rebuildFromJson = function (json) { + return new queryStructure.Group(json['title'], json['callstack']); + }; + return Group; +})(); +queryStructure.Selection = (function () { + __extends(Selection, queryStructure.Field); + function Selection(title, callstack, aggregation) { + this.title = title; + this.callstack = callstack; + this.aggregation = aggregation; + } + + Selection.prototype.toJson = function () { + return { "title": this.title, "callstack": this.callstack, 'aggregation': this.aggregation }; + }; + Selection.rebuildFromJson = function (json) { + return new queryStructure.Selection(json['title'], json['callstack'], json['aggregation']); + }; + return Selection; +})(); +queryStructure.Extraction = (function () { + function Extraction(selections, groups) { + this.selections = selections; + this.groups = groups; + } + + Extraction.prototype.toJson = function () { + var group, groupJson, selectJson, selection, _i, _j, _len, _len2, _ref, _ref2; + selectJson = []; + groupJson = []; + _ref = this.selections; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + selection = _ref[_i]; + selectJson.push(selection.toJson()); + } + _ref2 = this.groups; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + group = _ref2[_j]; + groupJson.push(group.toJson()); + } + return { "selections": selectJson, "groups": groupJson }; + }; + Extraction.rebuildFromJson = function (json) { + var group, groups, selection, selections, _i, _j, _len, _len2, _ref, _ref2; + selections = []; + groups = []; + _ref = json['selections']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + selection = _ref[_i]; + selections.push(queryStructure.Selection.rebuildFromJson(selection)); + } + _ref2 = json['groups']; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + group = _ref2[_j]; + groups.push(queryStructure.Group.rebuildFromJson(group)); + } + return new queryStructure.Extraction(selections, groups); + }; + return Extraction; +})(); + +var reducer; +reducer = this.reducer || {}; +reducer.Value = (function () { + function Value(values, rereduced) { + this.values = values; + this.rereduced = rereduced; + } + + Value.prototype.sum = function (title, element) { + if (!this.rereduced) this.values[title + '_sum'] = 0; + if (!element.rereduced) element.values[title + '_sum'] = 0; + return this.values[title + '_sum'] += element.values[title] + element.values[title + '_sum']; + }; + Value.prototype.frequency = function (title, element) { + var k, key, v, _ref, _results; + if (!this.rereduced) this.values[title + '_frequency'] = {}; + if (!element.rereduced) { + element.values[title + '_frequency'] = {}; + key = ('' + element.values[title]).replace('.', '~'); + element.values[title + '_frequency'][key] = 1; + } + _ref = element.values[title + '_frequency']; + _results = []; + for (k in _ref) { + v = _ref[k]; + if (this.values[title + '_frequency'][k] != null) { + _results.push(this.values[title + '_frequency'][k] += v); + } else { + _results.push(this.values[title + '_frequency'][k] = v); + } + } + return _results; + }; + Value.prototype.mean = function (title, element) { + var count, elementTotal, previousTotal, total; + if (!this.rereduced) { + this.values[title + '_mean'] = 0; + this.values[title + '_mean_count'] = 0; + } + if (!element.rereduced) { + element.values[title + '_mean'] = element.values[title]; + element.values[title + '_mean_count'] = 1; + } + previousTotal = this.values[title + '_mean'] * this.values[title + '_mean_count']; + elementTotal = element.values[title + '_mean'] * element.values[title + '_mean_count']; + total = previousTotal + elementTotal; + count = this.values[title + '_mean_count'] + element.values[title + '_mean_count']; + this.values[title + '_mean_count'] = count; + return this.values[title + '_mean'] = total / count; + }; + Value.prototype.median = function (title, element) { + var front_value, i, leftCenter, rightCenter, value, _i, _len, _ref; + if (!this.rereduced) this.values[title + '_median_list'] = []; + if (!element.rereduced) { + element.values[title + '_median_list'] = [element.values[title]]; + } + i = 0; + while (i < this.values[title + '_median_list'].length && element.values[title + '_median_list'].length > 0) { + while (element.values[title + '_median_list'].length > 0 && element.values[title + '_median_list'][0] < this.values[title + '_median_list'][i]) { + front_value = (element.values[title + '_median_list'].splice(0, 1))[0]; + this.values[title + '_median_list'].splice(i, 0, front_value); + i++; + } + i++; + } + _ref = element.values[title + '_median_list']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + value = _ref[_i]; + this.values[title + '_median_list'].splice(this.values[title + '_median_list'].length, 0, value); + } + if (this.values[title + '_median_list'].length % 2 === 0) { + leftCenter = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2)]; + rightCenter = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2) - 1]; + return this.values[title + '_median'] = (leftCenter + rightCenter) / 2; + } else { + return this.values[title + '_median'] = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2)]; + } + }; + Value.prototype.mode = function (title, element) { + var key, most_frequent_key, most_frequent_value, value, _ref, _ref2; + if (!this.rereduced) this.values[title + '_mode_frequency'] = {}; + if (!element.rereduced) { + element.values[title + '_mode_frequency'] = {}; + key = ('' + element.values[title]).replace('.', '~'); + element.values[title + '_mode_frequency'][key] = 1; + } + _ref = element.values[title + '_mode_frequency']; + for (key in _ref) { + value = _ref[key]; + if (this.values[title + '_mode_frequency'][key] != null) { + this.values[title + '_mode_frequency'][key] += 1; + } else { + this.values[title + '_mode_frequency'][key] = 1; + } + } + most_frequent_key = []; + most_frequent_value = 0; + _ref2 = this.values[title + '_mode_frequency']; + for (key in _ref2) { + value = _ref2[key]; + if (value === most_frequent_value) { + most_frequent_key.push(key); + } else if (value > most_frequent_value) { + most_frequent_key = [key]; + most_frequent_value = value; + } + } + return this.values[title + '_mode'] = most_frequent_key; + }; + return Value; +})(); +var __hasProp = Object.prototype.hasOwnProperty, __extends = function (child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; +}; +this.queryStructure || (this.queryStructure = {}); +queryStructure.Rule = (function () { + function Rule(name, data) { + this.name = name; + this.data = data; + this.type = this.constructor.name; + } + + Rule.prototype.toJson = function () { + return { "name": this.name, "type": this.type, "data": this.data }; + }; + return Rule; +})(); +queryStructure.Range = (function () { + function Range(category, title, field, start, end) { + this.category = category; + this.title = title; + this.field = field; + this.start = start; + this.end = end; + } + + return Range; +})(); +queryStructure.Comparison = (function () { + function Comparison(data) { + Comparison.__super__.constructor.call(this, "ComparisonRule", data); + } + + Comparison.prototype.test = function (patient) { + var value; + value = null; + if (this.field === 'age') { + value = patient[this.field](new Date()); + } else { + value = patient[this.field](); + } + if (this.comparator === '=') { + return value === this.value; + } else if (this.comparator === '<') { + return value < this.value; + } else { + return value > this.value; + } + }; + return Comparison; +})(); +queryStructure.CodeSetRule = (function () { + __extends(CodeSetRule, queryStructure.Rule); + function CodeSetRule(data) { + CodeSetRule.__super__.constructor.call(this, data.type, data); + this.code_set_type = data.type; + } + + CodeSetRule.prototype.test = function (p) { + var codes; + if (this.data.code === null) return true; + codes = p[this.code_set_type]().match(this.data.code.codes); + return codes.length !== 0; + }; + return CodeSetRule; +})(); +queryStructure.VitalSignRule = (function () { + __extends(VitalSignRule, queryStructure.Rule); + function VitalSignRule(data) { + VitalSignRule.__super__.constructor.call(this, "VitalSignRule", data); + } + + VitalSignRule.prototype.test = function (p) { + var codes; + if (this.data.code === null) return true; + codes = p.vitalSigns().match(this.data.code.codes); + return codes.length !== 0; + }; + return VitalSignRule; +})(); +queryStructure.EncounterRule = (function () { + __extends(EncounterRule, queryStructure.Rule); + function EncounterRule(data) { + EncounterRule.__super__.constructor.call(this, "EncounterRule", data); + } + + EncounterRule.prototype.test = function (p) { + var codes; + if (this.data.code === null) return true; + codes = p.encounters().match(this.data.code.codes); + return codes.length !== 0; + }; + return EncounterRule; +})(); +queryStructure.DemographicRule = (function () { + __extends(DemographicRule, queryStructure.Rule); + function DemographicRule(data) { + DemographicRule.__super__.constructor.call(this, "DemographicRule", data); + } + + DemographicRule.prototype.test = function (p) { + var match, status; + match = true; + if (this.data.ageRange) { + match = p.age() >= this.data.ageRange.low && p.age() <= this.data.ageRange.high; + } + if (this.data.maritalStatusCode && match) { + status = p.maritalStatus(); + match = status && status.includesCodeFrom(this.data.maritalStatusCode.codes); + } + if (this.data.gender && match) match = p.gender() === this.data.gender; + if (this.data.raceCode && match) { + match = p.race().includesCodeFrom(this.data.raceCode.codes); + } + return match; + }; + return DemographicRule; +})(); +queryStructure.RawJavascriptRule = (function () { + __extends(RawJavascriptRule, queryStructure.Rule); + function RawJavascriptRule(data) { + RawJavascriptRule.__super__.constructor.call(this, "RawJavascriptRule", data); + } + + RawJavascriptRule.prototype.test = function (p) { + if (this.data && this.data.js) { + try { + eval("var jscript = " + this.data.js); + return jscript(p); + } catch (_error) { + } + } + }; + return RawJavascriptRule; +})(); \ No newline at end of file diff --git a/test/fixtures/scoop/graphical_builder_demographics_reduce.js b/test/fixtures/scoop/graphical_builder_demographics_reduce.js new file mode 100644 index 0000000..7c105a5 --- /dev/null +++ b/test/fixtures/scoop/graphical_builder_demographics_reduce.js @@ -0,0 +1,687 @@ +function reduce(key, values) { + var result; + if (key.type == 'population') { + result = new reducer.Value({ 'target_pop': 0, 'filtered_pop': 0, 'unfound_pop': 0, 'total_pop': 0 }, rereduced = false); + for (var i = 0; i < values.length; i++) { + var _val = values[i]; + result.sum('target_pop', _val); + result.sum('filtered_pop', _val); + result.sum('unfound_pop', _val); + result.sum('total_pop', _val); + _val.rereduced = true; + result.rereduced = true; + } + } else if (key.type == 'group') { + result = new reducer.Value({ }, rereduced = false); + for (var j = 0; j < values.length; j++) { + var _val = values[j]; + result.rereduced = true; + _val.rereduced = true; + } + } + return result; +} +var reducer; +reducer = this.reducer || {}; +reducer.Value = (function () { + function Value(values, rereduced) { + this.values = values; + this.rereduced = rereduced; + } + + Value.prototype.sum = function (title, element) { + if (!this.rereduced) this.values[title + '_sum'] = 0; + if (!element.rereduced) element.values[title + '_sum'] = 0; + return this.values[title + '_sum'] += element.values[title] + element.values[title + '_sum']; + }; + Value.prototype.frequency = function (title, element) { + var k, key, v, _ref, _results; + if (!this.rereduced) this.values[title + '_frequency'] = {}; + if (!element.rereduced) { + element.values[title + '_frequency'] = {}; + key = ('' + element.values[title]).replace('.', '~'); + element.values[title + '_frequency'][key] = 1; + } + _ref = element.values[title + '_frequency']; + _results = []; + for (k in _ref) { + v = _ref[k]; + if (this.values[title + '_frequency'][k] != null) { + _results.push(this.values[title + '_frequency'][k] += v); + } else { + _results.push(this.values[title + '_frequency'][k] = v); + } + } + return _results; + }; + Value.prototype.mean = function (title, element) { + var count, elementTotal, previousTotal, total; + if (!this.rereduced) { + this.values[title + '_mean'] = 0; + this.values[title + '_mean_count'] = 0; + } + if (!element.rereduced) { + element.values[title + '_mean'] = element.values[title]; + element.values[title + '_mean_count'] = 1; + } + previousTotal = this.values[title + '_mean'] * this.values[title + '_mean_count']; + elementTotal = element.values[title + '_mean'] * element.values[title + '_mean_count']; + total = previousTotal + elementTotal; + count = this.values[title + '_mean_count'] + element.values[title + '_mean_count']; + this.values[title + '_mean_count'] = count; + return this.values[title + '_mean'] = total / count; + }; + Value.prototype.median = function (title, element) { + var front_value, i, leftCenter, rightCenter, value, _i, _len, _ref; + if (!this.rereduced) this.values[title + '_median_list'] = []; + if (!element.rereduced) { + element.values[title + '_median_list'] = [element.values[title]]; + } + i = 0; + while (i < this.values[title + '_median_list'].length && element.values[title + '_median_list'].length > 0) { + while (element.values[title + '_median_list'].length > 0 && element.values[title + '_median_list'][0] < this.values[title + '_median_list'][i]) { + front_value = (element.values[title + '_median_list'].splice(0, 1))[0]; + this.values[title + '_median_list'].splice(i, 0, front_value); + i++; + } + i++; + } + _ref = element.values[title + '_median_list']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + value = _ref[_i]; + this.values[title + '_median_list'].splice(this.values[title + '_median_list'].length, 0, value); + } + if (this.values[title + '_median_list'].length % 2 === 0) { + leftCenter = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2)]; + rightCenter = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2) - 1]; + return this.values[title + '_median'] = (leftCenter + rightCenter) / 2; + } else { + return this.values[title + '_median'] = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2)]; + } + }; + Value.prototype.mode = function (title, element) { + var key, most_frequent_key, most_frequent_value, value, _ref, _ref2; + if (!this.rereduced) this.values[title + '_mode_frequency'] = {}; + if (!element.rereduced) { + element.values[title + '_mode_frequency'] = {}; + key = ('' + element.values[title]).replace('.', '~'); + element.values[title + '_mode_frequency'][key] = 1; + } + _ref = element.values[title + '_mode_frequency']; + for (key in _ref) { + value = _ref[key]; + if (this.values[title + '_mode_frequency'][key] != null) { + this.values[title + '_mode_frequency'][key] += 1; + } else { + this.values[title + '_mode_frequency'][key] = 1; + } + } + most_frequent_key = []; + most_frequent_value = 0; + _ref2 = this.values[title + '_mode_frequency']; + for (key in _ref2) { + value = _ref2[key]; + if (value === most_frequent_value) { + most_frequent_key.push(key); + } else if (value > most_frequent_value) { + most_frequent_key = [key]; + most_frequent_value = value; + } + } + return this.values[title + '_mode'] = most_frequent_key; + }; + return Value; +})(); + +// utility functions called by reduce +var queryStructure = queryStructure || {}; +var __hasProp = Object.prototype.hasOwnProperty, __extends = function (child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; +}; +this.queryStructure || (this.queryStructure = {}); +queryStructure.Query = (function () { + function Query() { + this.find = new queryStructure.And(null); + this.filter = new queryStructure.And(null); + this.extract = new queryStructure.Extraction([], []); + } + + Query.prototype.toJson = function () { + return { 'find': this.find.toJson(), 'filter': this.filter.toJson(), 'extract': this.extract.toJson() }; + }; + Query.prototype.rebuildFromJson = function (json) { + this.find = json['find'] ? this.buildFromJson(null, json['find']) : new queryStructure.And(null); + this.filter = json['filter'] ? this.buildFromJson(null, json['filter']) : new queryStructure.And(null); + return this.extract = json['extract'] ? queryStructure.Extraction.rebuildFromJson(json['extract']) : new queryStructure.Extraction([], []); + }; + Query.prototype.buildFromJson = function (parent, element) { + var child, container, newContainer, ruleType, _i, _len, _ref; + if (this.getElementType(element) === 'rule') { + ruleType = element.type; + return new queryStructure[ruleType](element.data); + } else { + container = this.getContainerType(element); + newContainer = new queryStructure[container](parent, [], element.name, element.title, element.negate); + _ref = element[container.toLowerCase()]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + newContainer.add(this.buildFromJson(newContainer, child)); + } + return newContainer; + } + }; + Query.prototype.getElementType = function (element) { + if ((element['and'] != null) || (element['or'] != null)) { + return 'container'; + } else { + return 'rule'; + } + }; + Query.prototype.getContainerType = function (element) { + if (element['and'] != null) { + return 'And'; + } else if (element['or'] != null) { + return 'Or'; + } else { + return null; + } + }; + return Query; +})(); +queryStructure.Container = (function () { + function Container(parent, children, name, title, negate) { + this.parent = parent; + this.children = children != null ? children : []; + this.name = name; + this.title = title; + this.negate = negate != null ? negate : false; + this.children || (this.children = []); + } + + Container.prototype.add = function (element, after) { + var ci, index; + index = this.children.length; + ci = this.childIndex(after); + if (ci !== -1) index = ci + 1; + this.children.splice(index, 0, element); + if (element.parent && element.parent !== this) { + element.parent.removeChild(element); + } + element.parent = this; + return element; + }; + Container.prototype.addAll = function (items, after) { + var item, _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + _results.push(after = this.add(item, after)); + } + return _results; + }; + Container.prototype.remove = function () { + if (this.parent) return this.parent.removeChild(this); + }; + Container.prototype.removeChild = function (victim) { + var index; + index = this.childIndex(victim); + if (index !== -1) { + this.children.splice(index, 1); + return victim.parent = null; + } + }; + Container.prototype.replaceChild = function (child, newChild) { + var index; + index = this.childIndex(child); + if (index !== -1) { + this.children[index] = newChild; + child.parent = null; + return newChild.parent = this; + } + }; + Container.prototype.moveBefore = function (child, other) { + var i1, i2; + i1 = this.childIndex(child); + i2 = this.childIndex(other); + if (i1 !== -1 && i2 !== -1) { + child = this.children.splice(i2, 1); + this.children.splice(i1 - 1, 0, other); + return true; + } + return false; + }; + Container.prototype.childIndex = function (child) { + var index, _child, _ref; + if (child === null) return -1; + _ref = this.children; + for (index in _ref) { + _child = _ref[index]; + if (_child === child) return index; + } + return -1; + }; + Container.prototype.clear = function () { + return this.children = []; + }; + Container.prototype.childrenToJson = function () { + var child, childJson, js, _i, _len, _ref; + childJson = []; + _ref = this.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + js = child["toJson"] ? child.toJson() : child; + childJson.push(js); + } + return childJson; + }; + return Container; +})(); +queryStructure.Or = (function () { + __extends(Or, queryStructure.Container); + function Or() { + Or.__super__.constructor.apply(this, arguments); + } + + Or.prototype.toJson = function () { + var childJson; + childJson = this.childrenToJson(); + return { "name": this.name, "or": childJson, "negate": this.negate, "title": this.title }; + }; + Or.prototype.test = function (patient) { + var child, retval, _i, _len, _ref; + if (this.children.length === 0) return true; + retval = false; + _ref = this.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (child.test(patient)) { + retval = true; + break; + } + } + if (this.negate) { + return !retval; + } else { + return retval; + } + }; + return Or; +})(); +queryStructure.And = (function () { + __extends(And, queryStructure.Container); + function And() { + And.__super__.constructor.apply(this, arguments); + } + + And.prototype.toJson = function () { + var childJson; + childJson = this.childrenToJson(); + return { "name": this.name, "and": childJson, "negate": this.negate, "title": this.title }; + }; + And.prototype.test = function (patient) { + var child, retval, _i, _len, _ref; + if (this.children.length === 0) return true; + retval = true; + _ref = this.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (!child.test(patient)) { + retval = false; + break; + } + } + if (this.negate) { + return !retval; + } else { + return retval; + } + }; + return And; +})(); +queryStructure.Field = (function () { + function Field(title, callstack) { + this.title = title; + this.callstack = callstack; + } + + Field.prototype.toJson = function () { + return { "title": this.title, "callstack": this.callstack }; + }; + Field.prototype.extract = function (patient) { + return patient[callstack](); + }; + return Field; +})(); +queryStructure.Group = (function () { + __extends(Group, queryStructure.Field); + function Group(title, callstack) { + this.title = title; + this.callstack = callstack; + } + + Group.rebuildFromJson = function (json) { + return new queryStructure.Group(json['title'], json['callstack']); + }; + return Group; +})(); +queryStructure.Selection = (function () { + __extends(Selection, queryStructure.Field); + function Selection(title, callstack, aggregation) { + this.title = title; + this.callstack = callstack; + this.aggregation = aggregation; + } + + Selection.prototype.toJson = function () { + return { "title": this.title, "callstack": this.callstack, 'aggregation': this.aggregation }; + }; + Selection.rebuildFromJson = function (json) { + return new queryStructure.Selection(json['title'], json['callstack'], json['aggregation']); + }; + return Selection; +})(); +queryStructure.Extraction = (function () { + function Extraction(selections, groups) { + this.selections = selections; + this.groups = groups; + } + + Extraction.prototype.toJson = function () { + var group, groupJson, selectJson, selection, _i, _j, _len, _len2, _ref, _ref2; + selectJson = []; + groupJson = []; + _ref = this.selections; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + selection = _ref[_i]; + selectJson.push(selection.toJson()); + } + _ref2 = this.groups; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + group = _ref2[_j]; + groupJson.push(group.toJson()); + } + return { "selections": selectJson, "groups": groupJson }; + }; + Extraction.rebuildFromJson = function (json) { + var group, groups, selection, selections, _i, _j, _len, _len2, _ref, _ref2; + selections = []; + groups = []; + _ref = json['selections']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + selection = _ref[_i]; + selections.push(queryStructure.Selection.rebuildFromJson(selection)); + } + _ref2 = json['groups']; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + group = _ref2[_j]; + groups.push(queryStructure.Group.rebuildFromJson(group)); + } + return new queryStructure.Extraction(selections, groups); + }; + return Extraction; +})(); +var reducer; +reducer = this.reducer || {}; +reducer.Value = (function () { + function Value(values, rereduced) { + this.values = values; + this.rereduced = rereduced; + } + + Value.prototype.sum = function (title, element) { + if (!this.rereduced) this.values[title + '_sum'] = 0; + if (!element.rereduced) element.values[title + '_sum'] = 0; + return this.values[title + '_sum'] += element.values[title] + element.values[title + '_sum']; + }; + Value.prototype.frequency = function (title, element) { + var k, key, v, _ref, _results; + if (!this.rereduced) this.values[title + '_frequency'] = {}; + if (!element.rereduced) { + element.values[title + '_frequency'] = {}; + key = ('' + element.values[title]).replace('.', '~'); + element.values[title + '_frequency'][key] = 1; + } + _ref = element.values[title + '_frequency']; + _results = []; + for (k in _ref) { + v = _ref[k]; + if (this.values[title + '_frequency'][k] != null) { + _results.push(this.values[title + '_frequency'][k] += v); + } else { + _results.push(this.values[title + '_frequency'][k] = v); + } + } + return _results; + }; + Value.prototype.mean = function (title, element) { + var count, elementTotal, previousTotal, total; + if (!this.rereduced) { + this.values[title + '_mean'] = 0; + this.values[title + '_mean_count'] = 0; + } + if (!element.rereduced) { + element.values[title + '_mean'] = element.values[title]; + element.values[title + '_mean_count'] = 1; + } + previousTotal = this.values[title + '_mean'] * this.values[title + '_mean_count']; + elementTotal = element.values[title + '_mean'] * element.values[title + '_mean_count']; + total = previousTotal + elementTotal; + count = this.values[title + '_mean_count'] + element.values[title + '_mean_count']; + this.values[title + '_mean_count'] = count; + return this.values[title + '_mean'] = total / count; + }; + Value.prototype.median = function (title, element) { + var front_value, i, leftCenter, rightCenter, value, _i, _len, _ref; + if (!this.rereduced) this.values[title + '_median_list'] = []; + if (!element.rereduced) { + element.values[title + '_median_list'] = [element.values[title]]; + } + i = 0; + while (i < this.values[title + '_median_list'].length && element.values[title + '_median_list'].length > 0) { + while (element.values[title + '_median_list'].length > 0 && element.values[title + '_median_list'][0] < this.values[title + '_median_list'][i]) { + front_value = (element.values[title + '_median_list'].splice(0, 1))[0]; + this.values[title + '_median_list'].splice(i, 0, front_value); + i++; + } + i++; + } + _ref = element.values[title + '_median_list']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + value = _ref[_i]; + this.values[title + '_median_list'].splice(this.values[title + '_median_list'].length, 0, value); + } + if (this.values[title + '_median_list'].length % 2 === 0) { + leftCenter = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2)]; + rightCenter = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2) - 1]; + return this.values[title + '_median'] = (leftCenter + rightCenter) / 2; + } else { + return this.values[title + '_median'] = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2)]; + } + }; + Value.prototype.mode = function (title, element) { + var key, most_frequent_key, most_frequent_value, value, _ref, _ref2; + if (!this.rereduced) this.values[title + '_mode_frequency'] = {}; + if (!element.rereduced) { + element.values[title + '_mode_frequency'] = {}; + key = ('' + element.values[title]).replace('.', '~'); + element.values[title + '_mode_frequency'][key] = 1; + } + _ref = element.values[title + '_mode_frequency']; + for (key in _ref) { + value = _ref[key]; + if (this.values[title + '_mode_frequency'][key] != null) { + this.values[title + '_mode_frequency'][key] += 1; + } else { + this.values[title + '_mode_frequency'][key] = 1; + } + } + most_frequent_key = []; + most_frequent_value = 0; + _ref2 = this.values[title + '_mode_frequency']; + for (key in _ref2) { + value = _ref2[key]; + if (value === most_frequent_value) { + most_frequent_key.push(key); + } else if (value > most_frequent_value) { + most_frequent_key = [key]; + most_frequent_value = value; + } + } + return this.values[title + '_mode'] = most_frequent_key; + }; + return Value; +})(); +var __hasProp = Object.prototype.hasOwnProperty, __extends = function (child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; +}; +this.queryStructure || (this.queryStructure = {}); +queryStructure.Rule = (function () { + function Rule(name, data) { + this.name = name; + this.data = data; + this.type = this.constructor.name; + } + + Rule.prototype.toJson = function () { + return { "name": this.name, "type": this.type, "data": this.data }; + }; + return Rule; +})(); +queryStructure.Range = (function () { + function Range(category, title, field, start, end) { + this.category = category; + this.title = title; + this.field = field; + this.start = start; + this.end = end; + } + + return Range; +})(); +queryStructure.Comparison = (function () { + function Comparison(data) { + Comparison.__super__.constructor.call(this, "ComparisonRule", data); + } + + Comparison.prototype.test = function (patient) { + var value; + value = null; + if (this.field === 'age') { + value = patient[this.field](new Date()); + } else { + value = patient[this.field](); + } + if (this.comparator === '=') { + return value === this.value; + } else if (this.comparator === '<') { + return value < this.value; + } else { + return value > this.value; + } + }; + return Comparison; +})(); +queryStructure.CodeSetRule = (function () { + __extends(CodeSetRule, queryStructure.Rule); + function CodeSetRule(data) { + CodeSetRule.__super__.constructor.call(this, data.type, data); + this.code_set_type = data.type; + } + + CodeSetRule.prototype.test = function (p) { + var codes; + if (this.data.code === null) return true; + codes = p[this.code_set_type]().match(this.data.code.codes); + return codes.length !== 0; + }; + return CodeSetRule; +})(); +queryStructure.VitalSignRule = (function () { + __extends(VitalSignRule, queryStructure.Rule); + function VitalSignRule(data) { + VitalSignRule.__super__.constructor.call(this, "VitalSignRule", data); + } + + VitalSignRule.prototype.test = function (p) { + var codes; + if (this.data.code === null) return true; + codes = p.vitalSigns().match(this.data.code.codes); + return codes.length !== 0; + }; + return VitalSignRule; +})(); +queryStructure.EncounterRule = (function () { + __extends(EncounterRule, queryStructure.Rule); + function EncounterRule(data) { + EncounterRule.__super__.constructor.call(this, "EncounterRule", data); + } + + EncounterRule.prototype.test = function (p) { + var codes; + if (this.data.code === null) return true; + codes = p.encounters().match(this.data.code.codes); + return codes.length !== 0; + }; + return EncounterRule; +})(); +queryStructure.DemographicRule = (function () { + __extends(DemographicRule, queryStructure.Rule); + function DemographicRule(data) { + DemographicRule.__super__.constructor.call(this, "DemographicRule", data); + } + + DemographicRule.prototype.test = function (p) { + var match, status; + match = true; + if (this.data.ageRange) { + match = p.age() >= this.data.ageRange.low && p.age() <= this.data.ageRange.high; + } + if (this.data.maritalStatusCode && match) { + status = p.maritalStatus(); + match = status && status.includesCodeFrom(this.data.maritalStatusCode.codes); + } + if (this.data.gender && match) match = p.gender() === this.data.gender; + if (this.data.raceCode && match) { + match = p.race().includesCodeFrom(this.data.raceCode.codes); + } + return match; + }; + return DemographicRule; +})(); +queryStructure.RawJavascriptRule = (function () { + __extends(RawJavascriptRule, queryStructure.Rule); + function RawJavascriptRule(data) { + RawJavascriptRule.__super__.constructor.call(this, "RawJavascriptRule", data); + } + + RawJavascriptRule.prototype.test = function (p) { + if (this.data && this.data.js) { + try { + eval("var jscript = " + this.data.js); + return jscript(p); + } catch (_error) { + } + } + }; + return RawJavascriptRule; +})(); \ No newline at end of file diff --git a/test/fixtures/scoop/graphical_builder_generated_functions.js b/test/fixtures/scoop/graphical_builder_generated_functions.js new file mode 100644 index 0000000..74e76d1 --- /dev/null +++ b/test/fixtures/scoop/graphical_builder_generated_functions.js @@ -0,0 +1,551 @@ +var queryStructure = queryStructure || {}; +var __hasProp = Object.prototype.hasOwnProperty, __extends = function (child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; +}; +this.queryStructure || (this.queryStructure = {}); +queryStructure.Query = (function () { + function Query() { + this.find = new queryStructure.And(null); + this.filter = new queryStructure.And(null); + this.extract = new queryStructure.Extraction([], []); + } + + Query.prototype.toJson = function () { + return { 'find': this.find.toJson(), 'filter': this.filter.toJson(), 'extract': this.extract.toJson() }; + }; + Query.prototype.rebuildFromJson = function (json) { + this.find = json['find'] ? this.buildFromJson(null, json['find']) : new queryStructure.And(null); + this.filter = json['filter'] ? this.buildFromJson(null, json['filter']) : new queryStructure.And(null); + return this.extract = json['extract'] ? queryStructure.Extraction.rebuildFromJson(json['extract']) : new queryStructure.Extraction([], []); + }; + Query.prototype.buildFromJson = function (parent, element) { + var child, container, newContainer, ruleType, _i, _len, _ref; + if (this.getElementType(element) === 'rule') { + ruleType = element.type; + return new queryStructure[ruleType](element.data); + } else { + container = this.getContainerType(element); + newContainer = new queryStructure[container](parent, [], element.name, element.title, element.negate); + _ref = element[container.toLowerCase()]; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + newContainer.add(this.buildFromJson(newContainer, child)); + } + return newContainer; + } + }; + Query.prototype.getElementType = function (element) { + if ((element['and'] != null) || (element['or'] != null)) { + return 'container'; + } else { + return 'rule'; + } + }; + Query.prototype.getContainerType = function (element) { + if (element['and'] != null) { + return 'And'; + } else if (element['or'] != null) { + return 'Or'; + } else { + return null; + } + }; + return Query; +})(); +queryStructure.Container = (function () { + function Container(parent, children, name, title, negate) { + this.parent = parent; + this.children = children != null ? children : []; + this.name = name; + this.title = title; + this.negate = negate != null ? negate : false; + this.children || (this.children = []); + } + + Container.prototype.add = function (element, after) { + var ci, index; + index = this.children.length; + ci = this.childIndex(after); + if (ci !== -1) index = ci + 1; + this.children.splice(index, 0, element); + if (element.parent && element.parent !== this) { + element.parent.removeChild(element); + } + element.parent = this; + return element; + }; + Container.prototype.addAll = function (items, after) { + var item, _i, _len, _results; + _results = []; + for (_i = 0, _len = items.length; _i < _len; _i++) { + item = items[_i]; + _results.push(after = this.add(item, after)); + } + return _results; + }; + Container.prototype.remove = function () { + if (this.parent) return this.parent.removeChild(this); + }; + Container.prototype.removeChild = function (victim) { + var index; + index = this.childIndex(victim); + if (index !== -1) { + this.children.splice(index, 1); + return victim.parent = null; + } + }; + Container.prototype.replaceChild = function (child, newChild) { + var index; + index = this.childIndex(child); + if (index !== -1) { + this.children[index] = newChild; + child.parent = null; + return newChild.parent = this; + } + }; + Container.prototype.moveBefore = function (child, other) { + var i1, i2; + i1 = this.childIndex(child); + i2 = this.childIndex(other); + if (i1 !== -1 && i2 !== -1) { + child = this.children.splice(i2, 1); + this.children.splice(i1 - 1, 0, other); + return true; + } + return false; + }; + Container.prototype.childIndex = function (child) { + var index, _child, _ref; + if (child === null) return -1; + _ref = this.children; + for (index in _ref) { + _child = _ref[index]; + if (_child === child) return index; + } + return -1; + }; + Container.prototype.clear = function () { + return this.children = []; + }; + Container.prototype.childrenToJson = function () { + var child, childJson, js, _i, _len, _ref; + childJson = []; + _ref = this.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + js = child["toJson"] ? child.toJson() : child; + childJson.push(js); + } + return childJson; + }; + return Container; +})(); +queryStructure.Or = (function () { + __extends(Or, queryStructure.Container); + function Or() { + Or.__super__.constructor.apply(this, arguments); + } + + Or.prototype.toJson = function () { + var childJson; + childJson = this.childrenToJson(); + return { "name": this.name, "or": childJson, "negate": this.negate, "title": this.title }; + }; + Or.prototype.test = function (patient) { + var child, retval, _i, _len, _ref; + if (this.children.length === 0) return true; + retval = false; + _ref = this.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (child.test(patient)) { + retval = true; + break; + } + } + if (this.negate) { + return !retval; + } else { + return retval; + } + }; + return Or; +})(); +queryStructure.And = (function () { + __extends(And, queryStructure.Container); + function And() { + And.__super__.constructor.apply(this, arguments); + } + + And.prototype.toJson = function () { + var childJson; + childJson = this.childrenToJson(); + return { "name": this.name, "and": childJson, "negate": this.negate, "title": this.title }; + }; + And.prototype.test = function (patient) { + var child, retval, _i, _len, _ref; + if (this.children.length === 0) return true; + retval = true; + _ref = this.children; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + child = _ref[_i]; + if (!child.test(patient)) { + retval = false; + break; + } + } + if (this.negate) { + return !retval; + } else { + return retval; + } + }; + return And; +})(); +queryStructure.Field = (function () { + function Field(title, callstack) { + this.title = title; + this.callstack = callstack; + } + + Field.prototype.toJson = function () { + return { "title": this.title, "callstack": this.callstack }; + }; + Field.prototype.extract = function (patient) { + return patient[callstack](); + }; + return Field; +})(); +queryStructure.Group = (function () { + __extends(Group, queryStructure.Field); + function Group(title, callstack) { + this.title = title; + this.callstack = callstack; + } + + Group.rebuildFromJson = function (json) { + return new queryStructure.Group(json['title'], json['callstack']); + }; + return Group; +})(); +queryStructure.Selection = (function () { + __extends(Selection, queryStructure.Field); + function Selection(title, callstack, aggregation) { + this.title = title; + this.callstack = callstack; + this.aggregation = aggregation; + } + + Selection.prototype.toJson = function () { + return { "title": this.title, "callstack": this.callstack, 'aggregation': this.aggregation }; + }; + Selection.rebuildFromJson = function (json) { + return new queryStructure.Selection(json['title'], json['callstack'], json['aggregation']); + }; + return Selection; +})(); +queryStructure.Extraction = (function () { + function Extraction(selections, groups) { + this.selections = selections; + this.groups = groups; + } + + Extraction.prototype.toJson = function () { + var group, groupJson, selectJson, selection, _i, _j, _len, _len2, _ref, _ref2; + selectJson = []; + groupJson = []; + _ref = this.selections; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + selection = _ref[_i]; + selectJson.push(selection.toJson()); + } + _ref2 = this.groups; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + group = _ref2[_j]; + groupJson.push(group.toJson()); + } + return { "selections": selectJson, "groups": groupJson }; + }; + Extraction.rebuildFromJson = function (json) { + var group, groups, selection, selections, _i, _j, _len, _len2, _ref, _ref2; + selections = []; + groups = []; + _ref = json['selections']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + selection = _ref[_i]; + selections.push(queryStructure.Selection.rebuildFromJson(selection)); + } + _ref2 = json['groups']; + for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { + group = _ref2[_j]; + groups.push(queryStructure.Group.rebuildFromJson(group)); + } + return new queryStructure.Extraction(selections, groups); + }; + return Extraction; +})(); +var reducer; +reducer = this.reducer || {}; +reducer.Value = (function () { + function Value(values, rereduced) { + this.values = values; + this.rereduced = rereduced; + } + + Value.prototype.sum = function (title, element) { + if (!this.rereduced) this.values[title + '_sum'] = 0; + if (!element.rereduced) element.values[title + '_sum'] = 0; + return this.values[title + '_sum'] += element.values[title] + element.values[title + '_sum']; + }; + Value.prototype.frequency = function (title, element) { + var k, key, v, _ref, _results; + if (!this.rereduced) this.values[title + '_frequency'] = {}; + if (!element.rereduced) { + element.values[title + '_frequency'] = {}; + key = ('' + element.values[title]).replace('.', '~'); + element.values[title + '_frequency'][key] = 1; + } + _ref = element.values[title + '_frequency']; + _results = []; + for (k in _ref) { + v = _ref[k]; + if (this.values[title + '_frequency'][k] != null) { + _results.push(this.values[title + '_frequency'][k] += v); + } else { + _results.push(this.values[title + '_frequency'][k] = v); + } + } + return _results; + }; + Value.prototype.mean = function (title, element) { + var count, elementTotal, previousTotal, total; + if (!this.rereduced) { + this.values[title + '_mean'] = 0; + this.values[title + '_mean_count'] = 0; + } + if (!element.rereduced) { + element.values[title + '_mean'] = element.values[title]; + element.values[title + '_mean_count'] = 1; + } + previousTotal = this.values[title + '_mean'] * this.values[title + '_mean_count']; + elementTotal = element.values[title + '_mean'] * element.values[title + '_mean_count']; + total = previousTotal + elementTotal; + count = this.values[title + '_mean_count'] + element.values[title + '_mean_count']; + this.values[title + '_mean_count'] = count; + return this.values[title + '_mean'] = total / count; + }; + Value.prototype.median = function (title, element) { + var front_value, i, leftCenter, rightCenter, value, _i, _len, _ref; + if (!this.rereduced) this.values[title + '_median_list'] = []; + if (!element.rereduced) { + element.values[title + '_median_list'] = [element.values[title]]; + } + i = 0; + while (i < this.values[title + '_median_list'].length && element.values[title + '_median_list'].length > 0) { + while (element.values[title + '_median_list'].length > 0 && element.values[title + '_median_list'][0] < this.values[title + '_median_list'][i]) { + front_value = (element.values[title + '_median_list'].splice(0, 1))[0]; + this.values[title + '_median_list'].splice(i, 0, front_value); + i++; + } + i++; + } + _ref = element.values[title + '_median_list']; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + value = _ref[_i]; + this.values[title + '_median_list'].splice(this.values[title + '_median_list'].length, 0, value); + } + if (this.values[title + '_median_list'].length % 2 === 0) { + leftCenter = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2)]; + rightCenter = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2) - 1]; + return this.values[title + '_median'] = (leftCenter + rightCenter) / 2; + } else { + return this.values[title + '_median'] = this.values[title + '_median_list'][Math.floor(this.values[title + '_median_list'].length / 2)]; + } + }; + Value.prototype.mode = function (title, element) { + var key, most_frequent_key, most_frequent_value, value, _ref, _ref2; + if (!this.rereduced) this.values[title + '_mode_frequency'] = {}; + if (!element.rereduced) { + element.values[title + '_mode_frequency'] = {}; + key = ('' + element.values[title]).replace('.', '~'); + element.values[title + '_mode_frequency'][key] = 1; + } + _ref = element.values[title + '_mode_frequency']; + for (key in _ref) { + value = _ref[key]; + if (this.values[title + '_mode_frequency'][key] != null) { + this.values[title + '_mode_frequency'][key] += 1; + } else { + this.values[title + '_mode_frequency'][key] = 1; + } + } + most_frequent_key = []; + most_frequent_value = 0; + _ref2 = this.values[title + '_mode_frequency']; + for (key in _ref2) { + value = _ref2[key]; + if (value === most_frequent_value) { + most_frequent_key.push(key); + } else if (value > most_frequent_value) { + most_frequent_key = [key]; + most_frequent_value = value; + } + } + return this.values[title + '_mode'] = most_frequent_key; + }; + return Value; +})(); +var __hasProp = Object.prototype.hasOwnProperty, __extends = function (child, parent) { + for (var key in parent) { + if (__hasProp.call(parent, key)) child[key] = parent[key]; + } + function ctor() { + this.constructor = child; + } + + ctor.prototype = parent.prototype; + child.prototype = new ctor; + child.__super__ = parent.prototype; + return child; +}; +this.queryStructure || (this.queryStructure = {}); +queryStructure.Rule = (function () { + function Rule(name, data) { + this.name = name; + this.data = data; + this.type = this.constructor.name; + } + + Rule.prototype.toJson = function () { + return { "name": this.name, "type": this.type, "data": this.data }; + }; + return Rule; +})(); +queryStructure.Range = (function () { + function Range(category, title, field, start, end) { + this.category = category; + this.title = title; + this.field = field; + this.start = start; + this.end = end; + } + + return Range; +})(); +queryStructure.Comparison = (function () { + function Comparison(data) { + Comparison.__super__.constructor.call(this, "ComparisonRule", data); + } + + Comparison.prototype.test = function (patient) { + var value; + value = null; + if (this.field === 'age') { + value = patient[this.field](new Date()); + } else { + value = patient[this.field](); + } + if (this.comparator === '=') { + return value === this.value; + } else if (this.comparator === '<') { + return value < this.value; + } else { + return value > this.value; + } + }; + return Comparison; +})(); +queryStructure.CodeSetRule = (function () { + __extends(CodeSetRule, queryStructure.Rule); + function CodeSetRule(data) { + CodeSetRule.__super__.constructor.call(this, data.type, data); + this.code_set_type = data.type; + } + + CodeSetRule.prototype.test = function (p) { + var codes; + if (this.data.code === null) return true; + codes = p[this.code_set_type]().match(this.data.code.codes); + return codes.length !== 0; + }; + return CodeSetRule; +})(); +queryStructure.VitalSignRule = (function () { + __extends(VitalSignRule, queryStructure.Rule); + function VitalSignRule(data) { + VitalSignRule.__super__.constructor.call(this, "VitalSignRule", data); + } + + VitalSignRule.prototype.test = function (p) { + var codes; + if (this.data.code === null) return true; + codes = p.vitalSigns().match(this.data.code.codes); + return codes.length !== 0; + }; + return VitalSignRule; +})(); +queryStructure.EncounterRule = (function () { + __extends(EncounterRule, queryStructure.Rule); + function EncounterRule(data) { + EncounterRule.__super__.constructor.call(this, "EncounterRule", data); + } + + EncounterRule.prototype.test = function (p) { + var codes; + if (this.data.code === null) return true; + codes = p.encounters().match(this.data.code.codes); + return codes.length !== 0; + }; + return EncounterRule; +})(); +queryStructure.DemographicRule = (function () { + __extends(DemographicRule, queryStructure.Rule); + function DemographicRule(data) { + DemographicRule.__super__.constructor.call(this, "DemographicRule", data); + } + + DemographicRule.prototype.test = function (p) { + var match, status; + match = true; + if (this.data.ageRange) { + match = p.age() >= this.data.ageRange.low && p.age() <= this.data.ageRange.high; + } + if (this.data.maritalStatusCode && match) { + status = p.maritalStatus(); + match = status && status.includesCodeFrom(this.data.maritalStatusCode.codes); + } + if (this.data.gender && match) match = p.gender() === this.data.gender; + if (this.data.raceCode && match) { + match = p.race().includesCodeFrom(this.data.raceCode.codes); + } + return match; + }; + return DemographicRule; +})(); +queryStructure.RawJavascriptRule = (function () { + __extends(RawJavascriptRule, queryStructure.Rule); + function RawJavascriptRule(data) { + RawJavascriptRule.__super__.constructor.call(this, "RawJavascriptRule", data); + } + + RawJavascriptRule.prototype.test = function (p) { + if (this.data && this.data.js) { + try { + eval("var jscript = " + this.data.js); + return jscript(p); + } catch (_error) { + } + } + }; + return RawJavascriptRule; +})(); \ No newline at end of file diff --git a/test/fixtures/scoop/renal_digoxin_map.js b/test/fixtures/scoop/renal_digoxin_map.js new file mode 100644 index 0000000..74bd7ed --- /dev/null +++ b/test/fixtures/scoop/renal_digoxin_map.js @@ -0,0 +1,80 @@ +function map(patient) { + var targetMedicationCodes = { + "whoATC": ["C01AA05"], + "HC-DIN": ["02281236", "02281228", "02281201", "02245428", "02245427", + "02245426", "02048264", "02048272", "0021415", "00698296", "00647470"] + }; + + var targetLabCodes = { + "pCLOCD": ["45066-8", "2160-0", "33914-3", "50044-7", "48642-3", "48643-1"] + }; + + var ageLimit = 65; + + var drugList = patient.medications(); + var resultList = patient.results(); + + var now = new Date(2013, 10, 30); + var start = new Date(2000, 6, 1); + var end = addDate(now, 0, 1, 0); + + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks if patient is older than ageLimit + function population(patient) { + return (patient.age(now) >= ageLimit); + } + + // Checks for Creatinine labs performed within the last year + function hasLabCode() { + return resultList.match(targetLabCodes, addDate(now, -1, 0, 0), end).length; + } + + // Checks for existence of Digoxin + function hasMedication() { + return drugList.match(targetMedicationCodes, start, end).length; + } + + function hasCurrentMedication() { + for (var i = 0; i < drugList.length; i++) { + var tmpArray = new hQuery.CodedEntryList(); + tmpArray[0] = drugList[i]; + if (tmpArray.match(targetMedicationCodes)) { + var drugStart = drugList[i].indicateMedicationStart().getTime(); + var drugEnd = drugList[i].indicateMedicationStop().getTime(); + + // Check if drug is within the right time + if (drugEnd >= now && drugStart <= now) { + return true; + } + } + } + return false; + } + + emit('total_pop', 1); + + if (population(patient)) { + //emit("senior_pop: " + patient.given() + " " + patient.last(), 1); + emit("senior_pop", 1); + if (hasLabCode()) { + if (hasMedication() && hasCurrentMedication()) { + //emit("Digoxin: " + patient.given() + " " + patient.last(), 1); + //emit("Creatinine: " + patient.given() + " " + patient.last(), 1); + var c = patient.results(); + for (var i = 0; i < c.length; i++) { + if (c[i].interpretation().code() == "A") { + //emit("Abnormal Creatinine: " + patient.given() + " " + patient.last(), 1); + emit("senior_pop_digoxin_creatinine_abnormal", 1); + } + } + } + } + } +} diff --git a/test/fixtures/scoop/scoop_general_reduce.js b/test/fixtures/scoop/scoop_general_reduce.js new file mode 100644 index 0000000..f086eed --- /dev/null +++ b/test/fixtures/scoop/scoop_general_reduce.js @@ -0,0 +1,3 @@ +function reduce(key, values) { + return Array.sum(values); +} diff --git a/test/fixtures/scoop/vital_sign_overweight_map.js b/test/fixtures/scoop/vital_sign_overweight_map.js new file mode 100644 index 0000000..8c0dd16 --- /dev/null +++ b/test/fixtures/scoop/vital_sign_overweight_map.js @@ -0,0 +1,119 @@ +// Extends Query Title: BMI or WC documented in last 2 yrs age > 19 +// +// Illustrates retrieval of height, weight and waist circumference values from +// clinical observations and the calculation of BMI based on this information. +function map(patient) { + var targetWaistCircumferenceCodes = { + "LOINC": ["56115-9"] + }; + + var targetHeightCodes = { + "LOINC": ["8302-2"] + } + + var targetWeightCodes = { + "LOINC": ["3141-9"] + } + + var ageLimit = 19; + + var wcLimit = 90; // waist circumference threshold (cm) + + var vitalSignList = patient.vitalSigns(); + + var now = new Date(2013, 10, 30); + var start = addDate(now, -2, 0, 0); + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks if patient is older than ageLimit + function population(patient) { + return (patient.age(now) > ageLimit); + } + + + // Checks for existence of waist circumference observation + function hasWaistCircumference() { + return vitalSignList.match(targetWaistCircumferenceCodes, start, end).length; + } + + function hasHeight() { + return vitalSignList.match(targetHeightCodes, start, end).length; + } + + function hasWeight() { + return vitalSignList.match(targetWeightCodes, start, end).length; + } + + // http://en.wikipedia.org/wiki/Body_mass_index + function calculateBMI(height, weight, metric) { + if (metric) { + bmi = weight/(height/100.0)^2; // assume cm and kg + } else { + bmi = 703 * weight /height^2; // assume in and lb + } + return bmi; + } + + function hasWaistCircumferenceIndicator() { + for (var i = 0; i < vitalSignList.length; i++) { + //if (vitalSignList[i].values()[0].units() == "cm") { + if (vitalSignList[i].includesCodeFrom(targetWaistCircumferenceCodes) && + vitalSignList[i].values()[0].scalar() > wcLimit) { + return true; + } + //} + } + return false; + } + + + function hasHeightWeightIndicators() { + var height = 0; + var weight = 0; + var bmi = 0; + for (var i = 0; i < vitalSignList.length; i++) { + //if (vitalSignList[i].values()[0].units() == "cm") { + if (vitalSignList[i].includesCodeFrom(targetHeightCodes)) { + height = vitalSignList[i].values()[0].scalar(); + //emit("height="+height,1); + } + if (vitalSignList[i].includesCodeFrom(targetWeightCodes)) { + weight = vitalSignList[i].values()[0].scalar(); + //emit("weight="+weight,1); + } + if (height != 0 && weight != 0) { + bmi = calculateBMI(height,weight,true); + //emit("bmi="+bmi,1); + return bmi > 30; + } + //} + } + return false; + } + + emit('total_pop', 1); + + if (population(patient)) { + //emit("senior_pop: " + patient.given() + " " + patient.last(), 1); + emit(">19_pop", 1); + if (hasWaistCircumference() && hasWaistCircumferenceIndicator()) { + emit(">19_pop_overweight_wc", 1); + } else { + emit(">19_pop_overweight_wc", 0) + }; + if (hasHeightWeightIndicators()) { + emit(">19_pop_bmi>30",1); + } else { + emit(">19_pop_bmi>30",0); + }; + } +} \ No newline at end of file diff --git a/test/fixtures/scoop/vital_signs_map.js b/test/fixtures/scoop/vital_signs_map.js new file mode 100644 index 0000000..0cca4cb --- /dev/null +++ b/test/fixtures/scoop/vital_signs_map.js @@ -0,0 +1,131 @@ +// Supports Query Title: BMI or WC documented in last 2 yrs age > 19 +// +// Also illustrates detecting the presence of vital sign information for heart +// rate, blood pressure, temperature, height, weight and waist circumference. +function map(patient) { + var targetHeartRateCodes = { + "LOINC": ["8867-4"] + }; + + var targetBloodPressureCodes = { + "LOINC": ["55284-4"] + }; + + var targetBloodPressureSystolicCodes = { + "LOINC": ["8480-6"] + }; + + var targetBloodPressureDiastolicCodes = { + "LOINC": ["8462-4"] + }; + + var targetTemperatureCodes = { + "LOINC": ["8310-5"] + }; + + var targetHeightCodes = { + "LOINC": ["8302-2"] + }; + + var targetWeightCodes = { + "LOINC": ["3141-9"] + }; + + var targetWaistCircumferenceCodes = { + "LOINC": ["56115-9"] + }; + + var ageLimit = 19; + + var vitalSignList = patient.vitalSigns(); + + var now = new Date(2013, 10, 30); + var start = addDate(now, -2, 0, 0); + var end = addDate(now, 0, 0, 0); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // Checks if patient is older than ageLimit + function population(patient) { + return (patient.age(now) > ageLimit); + } + + + // Checks for existence of heart rate observation + function hasHeartRate() { + return vitalSignList.match(targetHeartRateCodes, start, end).length; + } + + // Checks for existence of blood pressure observation + function hasBloodPressure() { + return vitalSignList.match(targetBloodPressureCodes, start, end).length; + } + + // Checks for existence of systolic blood pressure observation + function hasSystolicBloodPressure() { + return vitalSignList.match(targetBloodPressureSystolicCodes, start, end).length; + } + + // Checks for existence of diastolic blood pressure observation + function hasDiastolicBloodPressure() { + return vitalSignList.match(targetBloodPressureDiastolicCodes, start, end).length; + } + + // Checks for existence of temperature observation + function hasTemperature() { + return vitalSignList.match(targetTemperatureCodes, start, end).length; + } + + // Checks for existence of height observation + function hasHeight() { + return vitalSignList.match(targetHeightCodes, start, end).length; + } + + // Checks for existence of weight observation + function hasWeight() { + return vitalSignList.match(targetWeightCodes, start, end).length; + } + + // Checks for existence of waist circumference observation + function hasWC() { + return vitalSignList.match(targetWaistCircumferenceCodes, start, end).length; + } + + emit('total_pop', 1); + + if (population(patient)) { + //emit("senior_pop: " + patient.given() + " " + patient.last(), 1); + emit(">19_pop", 1); + if (hasHeartRate()) { + emit(">19_pop_heartrate", 1); + } + if (hasBloodPressure()) { + emit(">19_pop_bp",1) + } + if (hasSystolicBloodPressure()) { + emit(">19_pop_bp_systolic",1) + } + if (hasDiastolicBloodPressure()) { + emit(">19_pop_bp_diastolic",1) + } + if (hasTemperature()) { + emit(">19_pop_temperature", 1); + } + if (hasHeight()) { + emit(">19_pop_height", 1); + } + if (hasWeight()) { + emit(">19_pop_weight", 1); + } + if (hasWC()) { + emit(">19_pop_wc", 1); + } + } +} \ No newline at end of file diff --git a/test/fixtures/ubc/average_num_medications.js b/test/fixtures/ubc/average_num_medications.js new file mode 100644 index 0000000..ee49300 --- /dev/null +++ b/test/fixtures/ubc/average_num_medications.js @@ -0,0 +1,90 @@ +// Reference Number: UBC-008 +// Query Title: Average number of prescriptions +// +// Created by rrusk on 2013-11-28. +// +// Equivalent SQL: +// +// Numerator: +// SELECT +// COUNT(d.drugid) AS Count +// FROM +// drugs AS d +// WHERE +// d.rx_date >= DATE_SUB( NOW(), INTERVAL 12 MONTH ) AND +// d.archived = 0 +// +// Denominator: +// SELECT +// COUNT(DISTINCT d.demographic_no) AS 'Count' +// FROM +// drugs AS d +// WHERE +// d.rx_date >= DATE_SUB( NOW(), INTERVAL 12 MONTH ) AND +// d.archived = 0 + +// There is no drug object in the mongodb. All medications are attached to specific, active patients +// so it is not possible to duplicate the previous OSCAR SQL query exactly. This calculation is similar. +// though. + +function map(patient) { + var now = new Date(); + var startDate = addDate(now, -1, 0, 0); // last 12 months + + var drugList = patient.medications(); + var currentDrugs; + + if (drugList === null || drugList.length === 0) { + emit('patients_no_medication_record', 1); + } else { + emit('patients_with_medication_record', 1); + currentDrugs = findCurrentDrugs(drugList); + } + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + function isCurrentDrug(drug) { + var start = drug.indicateMedicationStart().getTime(); + return (start >= startDate); + } + + // Find uncoded drugs that are between start & end date + function findCurrentDrugs(drugs) { + + for(var i = 0; i < drugs.length; i++) { + + var codes = drugs[i].medicationInformation().codedProduct(); + + if (codes === null || codes.length == 0) { + emit('medication_no_codedProduct', 1); + } else { + // Check if drug is within the right time + var j; + if(isCurrentDrug(drugs[i])) { + for (j = 0; j < codes.length; j++) { + emit('medication_last12months', 1); + } + } else { + for (j = 0; j < codes.length; j++) { + emit('medication_prior_to_last12months', 1); + } + } + } + } + } + + emit('total_population', 1); + + // Empty Case + emit('patients_no_medication_record', 0); + emit('patients_with_medication_record', 0); + emit('medication_last12months', 0); + emit('medication_prior_to_last12months', 0); +} \ No newline at end of file diff --git a/test/fixtures/ubc/ubc_general_reduce.js b/test/fixtures/ubc/ubc_general_reduce.js new file mode 100644 index 0000000..53e9d84 --- /dev/null +++ b/test/fixtures/ubc/ubc_general_reduce.js @@ -0,0 +1,7 @@ +/** + * Created by rrusk on 2013-11-29. + */ + +function reduce(key, values) { + return Array.sum(values); +} \ No newline at end of file diff --git a/test/fixtures/ubc/ubc_polypharmacy.js b/test/fixtures/ubc/ubc_polypharmacy.js new file mode 100644 index 0000000..98e9eae --- /dev/null +++ b/test/fixtures/ubc/ubc_polypharmacy.js @@ -0,0 +1,188 @@ +// Reference Number: UBC-001 +// Query Title: Patients, 65 and older, on 5 or more medications +// Reference Number: UBC-002 +// Query Title: Patients, 65 and older, on 10 or more medications +// Created by rrusk on 2013-12-06. + +function map(patient) { + var ageLimit = 65; + var drugLimit = 5; // Change this value to number of active medications to count + var now = new Date(); + + var drugList = patient.medications(); + var currentUniqueDrugsIncludingPRN = findUniqueCurrentDrugsIncludingPRN(drugList); + var currentUniqueDrugsWithoutPRN = findUniqueCurrentDrugsWithoutPRN(drugList); + var currentNonUniqueDrugsIncludingPRN = findNonUniqueCurrentDrugsIncludingPRN(drugList); + var currentNonUniqueDrugsWithoutPRN = findNonUniqueCurrentDrugsWithoutPRN(drugList); + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + // a and b are javascript Date objects + // Returns a with the 1.2x calculated date offset added in + function endDateOffset(a, b) { + var start = new Date(a); + var end = new Date(b); + var diff = Math.floor((end-start) / (1000*3600*24)); + var offset = Math.floor(1.2 * diff); + return addDate(start, 0, 0, offset); + } + + function isCurrentDrug(drug) { + var drugStart = drug.indicateMedicationStart().getTime(); + var drugEnd = drug.indicateMedicationStop().getTime(); + + return (endDateOffset(drugStart, drugEnd) >= now && drugStart <= now); + } + + // Returns count of "active" drugs that are between start & end date + // Also checks for the same "active" drug and doesn't overcount + function findUniqueCurrentDrugsIncludingPRN(drugs) { + var count = 0; + var seenDrugs = []; + + for(var i = 0; i < drugs.length; i++) { + var repeat = false; + + // Check if drug is PRN or within the right time + if(drugs[i].freeTextSig().indexOf(" E2E_PRN_FLAG") !== -1 + || isCurrentDrug(drugs[i])) { + // Check if this entry is a repeat of same drug (codesystem agnostic) + var codes = drugs[i].medicationInformation().codedProduct(); + + for (var j = 0; j < codes.length; j++) { + var code = codes[j].code(); + + if(seenDrugs.indexOf(code) === -1) { + seenDrugs.push(code); + } + else { + repeat = true; + } + } + + // Increment count if not a repeat + if(!repeat) { + count++; + } + } + } + + return count; + } + + // Returns count of "active" drugs that are between start & end date + // Also checks for the same "active" drug and doesn't overcount + function findUniqueCurrentDrugsWithoutPRN(drugs) { + var count = 0; + var seenDrugs = []; + + for(var i = 0; i < drugs.length; i++) { + var repeat = false; + + // Check if drug is within the right time + if(isCurrentDrug(drugs[i])) { + + // check whether drugs[i] is a PRN; if it is skip + if (drugs[i].freeTextSig().indexOf(" E2E_PRN_FLAG") !== -1) { + continue; // continue on to next drug immediately + } + + // Check if this entry is a repeat of same drug (codesystem agnostic) + var codes = drugs[i].medicationInformation().codedProduct(); + + for (var j = 0; j < codes.length; j++) { + var code = codes[j].code(); + + if(seenDrugs.indexOf(code) === -1) { + seenDrugs.push(code); + } + else { + repeat = true; + } + } + + // Increment count if not a repeat + if(!repeat) { + count++; + } + } + } + + return count; + } + + // Returns count of "active" drugs that are between start & end date + function findNonUniqueCurrentDrugsIncludingPRN(drugs) { + var count = 0; + + for(var i = 0; i < drugs.length; i++) { + var repeat = false; + + // Check if drug is PRN or within the right time + if(drugs[i].freeTextSig().indexOf(" E2E_PRN_FLAG") !== -1 + || isCurrentDrug(drugs[i])) { + count++; + } + } + + return count; + } + + // Returns count of "active" drugs that are between start & end date + function findNonUniqueCurrentDrugsWithoutPRN(drugs) { + var count = 0; + var seenDrugs = []; + + for(var i = 0; i < drugs.length; i++) { + var repeat = false; + + // Check if drug is within the right time + if(isCurrentDrug(drugs[i])) { + // check whether drugs[i] is a PRN; if it is skip + if (drugs[i].freeTextSig().indexOf(" E2E_PRN_FLAG") !== -1) { + continue; // continue on to next drug immediately + } + count++; + } + } + + return count; + } + + emit('total_population', 1); + if (patient.age(now) >= ageLimit) { + emit('denominator_sampled_number', 1); + + // Adds patient to count if over ageLimit & over drugLimit + if (currentUniqueDrugsIncludingPRN >= drugLimit) { + emit('numerator_polypharmacy_number_including_prn', 1); + } + // Adds patient to count if over ageLimit & over drugLimit + if (currentUniqueDrugsWithoutPRN > drugLimit) { + emit('numerator_polypharmacy_number_without_prn', 1); + } + + // Adds patient to count if over ageLimit & over drugLimit + if (currentNonUniqueDrugsIncludingPRN >= drugLimit) { + emit('numerator_polypharmacy_number_nonunique_including_prn', 1); + } + // Adds patient to count if over ageLimit & over drugLimit + if (currentNonUniqueDrugsWithoutPRN > drugLimit) { + emit('numerator_polypharmacy_number_nonunique_without_prn', 1); + } + + // Empty Case + emit('numerator_polypharmacy_number_including_prn', 0); + emit('numerator_polypharmacy_number_without_prn', 0); + emit('numerator_polypharmacy_number_nonunique_including_prn', 0); + emit('numerator_polypharmacy_number_nonunique_without_prn', 0); + emit('denominator_sampled_number', 0); + } +} diff --git a/test/fixtures/ubc/uncoded_medications.js b/test/fixtures/ubc/uncoded_medications.js new file mode 100644 index 0000000..f228b06 --- /dev/null +++ b/test/fixtures/ubc/uncoded_medications.js @@ -0,0 +1,106 @@ +// Reference Number: UBC-007 +// Query Title: Prescriptions without medication codes +// +// Equivalent SQL: +// +// Numerator: +// SELECT +// COUNT(d.drugid) AS Count +// FROM +// drugs AS d +// WHERE +// d.rx_date >= DATE_SUB( NOW(), INTERVAL 12 MONTH ) AND +// (d.regional_identifier IS NULL OR d.regional_identifier = '') AND +// (d.ATC IS NULL OR d.ATC = '') AND +// d.archived = 0; +// +// Denominator: +// SELECT +// COUNT(d.drugid) AS Count +// FROM +// drugs AS d +// WHERE +// d.rx_date >= DATE_SUB( NOW(), INTERVAL 12 MONTH ) AND +// d.archived = 0; + + +function map(patient) { + var now = new Date(); + var startDate = addDate(now, -1, 0, 0); // last 12 months + + var drugList = patient.medications(); + + if (drugList === null || drugList.length === 0) { + emit('patients_no_medication_record', 1); + } else { + emit('patients_with_medication_record', 1); + findCurrentDrugs(drugList); + } + + + // Shifts date by year, month, and date specified + function addDate(date, y, m, d) { + var n = new Date(date); + n.setFullYear(date.getFullYear() + (y || 0)); + n.setMonth(date.getMonth() + (m || 0)); + n.setDate(date.getDate() + (d || 0)); + return n; + } + + function isCurrentDrug(drug) { + var start = drug.indicateMedicationStart().getTime(); + return (start >= startDate); + } + + // Find uncoded drugs that are between start & end date + function findCurrentDrugs(drugs) { + + for(var i = 0; i < drugs.length; i++) { + + var codes = drugs[i].medicationInformation().codedProduct(); + + if (drugs[i].freeTextSig().indexOf(" E2E_PRN_FLAG") !== -1) { + emit("E2E_PRN_FLAG", 1); + } + + if (codes === null || codes.length === 0) { + emit('medication_no_codedProduct', 1); + } else { + // Check if drug is within the right time + var j; + if(isCurrentDrug(drugs[i])) { + for (j = 0; j < codes.length; j++) { + // check for missing DIN or ATC codes + if (codes[j].codeSystemName().toLowerCase() !== null && + codes[j].codeSystemName().toLowerCase() !== "whoATC".toLowerCase() && + codes[j].codeSystemName().toLowerCase() !== "HC-DIN".toLowerCase()) { + emit('medication_last12months_uncoded', 1); + } else { + // show code types + emit('medication_last12months_coded_'+codes[j].codeSystemName().toLowerCase(), 1); + } + } + } else { + for (j = 0; j < codes.length; j++) { + if (codes[j].codeSystemName().toLowerCase() !== null && + codes[j].codeSystemName().toLowerCase() !== "whoATC".toLowerCase() && + codes[j].codeSystemName().toLowerCase() !== "HC-DIN".toLowerCase()) { + emit('medication_prior_to_last12months_uncoded', 1); + } else { + emit('medication_prior_to_last12months_coded_'+codes[j].codeSystemName().toLowerCase(), 1); + } + } + } + } + } + } + + emit('total_population', 1); + + // Empty Case + emit('patients_no_medication_record', 0); + emit('patients_with_medication_record', 0); + emit('medication_no_codedProduct', 0); + emit('medication_last12months_uncoded', 0); + emit('medication_prior_to_last12months_uncoded', 0); +} diff --git a/test/functional/.gitkeep b/test/functional/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/functional/pmn_controller_test.rb b/test/functional/pmn_controller_test.rb index 49f8f02..15198d5 100644 --- a/test/functional/pmn_controller_test.rb +++ b/test/functional/pmn_controller_test.rb @@ -28,7 +28,8 @@ def parse_response_body assert_equal '1', doc.xpath('//pmn:DesiredDocuments/ms:string[1]').inner_text request_id = doc.at_xpath('//pmn:RequestResult').inner_text assert request_id - r = PMNRequest.first(:conditions => {:doc_id => '1'}) + #r = PMNRequest.first(:conditions => {:doc_id => '1'}) + r = PMNRequest.where(doc_id: '1').first assert r assert_equal "multipart/form-data; boundary=-----------RubyMultipartPost", r.mime_type assert_equal nil, r.content @@ -40,6 +41,7 @@ def parse_response_body assert_response :success assert_equal 'application/xml', @response.content_type r.reload + # TODO This test should be updated with an add_document.xml that doesn't use hasNext() in the reduce function assert_equal "-------------RubyMultipartPost\r\nContent-Disposition: form-data; name=\"map\"; filename=\"local.path\"\r\nContent-Length: 56\r\nContent-Type: application/javascript\r\nContent-Transfer-Encoding: binary\r\n\r\nfunction map(patient) {\r\n emit(patient.gender(), 1);\r\n}\r\n-------------RubyMultipartPost\r\nContent-Disposition: form-data; name=\"reduce\"; filename=\"local.path\"\r\nContent-Length: 123\r\nContent-Type: application/javascript\r\nContent-Transfer-Encoding: binary\r\n\r\nfunction reduce(gender, iter) {\r\n var sum = 0;\r\n while(iter.hasNext()) {\r\n sum += iter.next();\r\n }\r\n return sum;\r\n};\r\n-------------RubyMultipartPost\r\nContent-Disposition: form-data; name=\"filter\"; filename=\"local.path\"\r\nContent-Length: 0\r\nContent-Type: application/json\r\nContent-Transfer-Encoding: binary\r\n\r\n\r\n-------------RubyMultipartPost\r\nContent-Disposition: form-data; name=\"functions\"; filename=\"local.path\"\r\nContent-Length: 0\r\nContent-Type: application/json\r\nContent-Transfer-Encoding: binary\r\n\r\n\r\n-------------RubyMultipartPost--\r\n\r\n", r.content @request.env['RAW_POST_DATA'] = nil diff --git a/test/functional/queries_controller_test.rb b/test/functional/queries_controller_test.rb index 31afa7b..a66eb24 100644 --- a/test/functional/queries_controller_test.rb +++ b/test/functional/queries_controller_test.rb @@ -7,8 +7,8 @@ class QueriesControllerTest < ActionController::TestCase end test "should get an atom feed at index" do - Factory(:successful_job) - Factory(:successful_job) + FactoryGirl.create(:successful_job) + FactoryGirl.create(:successful_job) get :index, :format => :atom assert_response :success end @@ -58,7 +58,7 @@ class QueriesControllerTest < ActionController::TestCase end test 'should show JSON for a successful job' do - query = Factory(:successful_job) + query = FactoryGirl.create(:successful_job) get :show, :id => query.id.to_s assert_response :success end diff --git a/test/functional/records_controller_test.rb b/test/functional/records_controller_test.rb index 983b190..9308b1e 100644 --- a/test/functional/records_controller_test.rb +++ b/test/functional/records_controller_test.rb @@ -10,9 +10,61 @@ class RecordsControllerTest < ActionController::TestCase c32 = Rack::Test::UploadedFile.new(File.join(Rails.root, 'test', 'fixtures', 'TobaccoUser0028.xml'), 'application/xml') post :create, {:content => c32} assert_response 201 - r = Mongoid.master['records'].find_one({:first => 'Unit', :last => 'Test'}) + db = Mongoid.default_session + #r = Mongoid.master['records'].find_one({:first => 'Unit', :last => 'Test'}) + r = db['records'].where({:first => 'Unit', :last => 'Test'}).first assert r assert_equal -773020800, r['birthdate'] end + test "should POST a E2E to create" do + e2e = Rack::Test::UploadedFile.new(File.join(Rails.root, 'test', 'fixtures', 'JOHN_CLEESE_1_25091940.xml'), 'application/xml') + post :create, {:content => e2e} + assert_response 201 + db = Mongoid.default_session + assert_equal 501, db[:records].find.count + #r = db['records'].where({:first => 'JOHN', :last => 'CLEESE'}).first + r = db[:records].where({ hash_id: 'oqG3YBB7rJvxeUAmPu2Mv2Q/cUji905I9IoJ4w==' }).first + refute_nil r + assert_equal '1', r['_id'] + assert_equal '1', r['emr_demographics_primary_key'] + assert_equal 'cpsid', r['primary_care_provider_id'] + assert_equal "m59ceyj+C/6mnU2V32L/0G5XHZ3folWFlz8NTg==", r['medical_record_number'] + assert_equal "s/Q1SdAMY/S6mlao6erGW8sO1N0Z5XYXsSd2Ug==", r['first'] + assert_equal "7ETUHfZcSQduD+JS3qauh9vPmWUp1xbe56I3Bw==", r['last'] + assert_equal -923616000, r['birthdate'] + assert_equal "M", r['gender'] + performer = r['encounters'][0]['performer'] + assert_equal "", performer['given_name'] + assert_equal "qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==", performer['family_name'] + assert_equal performer['family_name'], performer['npi'] + #assert_equal "doctor", performer['given_name'] + #assert_equal "oscardoc", performer['family_name'] + #assert_equal "cpsid", performer['npi'] + end + + test "should POST another E2E to create" do + e2e = Rack::Test::UploadedFile.new(File.join(Rails.root, 'test', 'fixtures', 'MZarilla.xml'), 'application/xml') + post :create, {:content => e2e} + assert_response 201 + db = Mongoid.default_session + assert_equal 501, db[:records].find.count + #r = db['records'].where({:first => 'Melvin', :last => 'Zarilla'}).first + r = db[:records].where({ hash_id: '1vw2LeZgjRXW1Z00Xi97WII5Tbh0ln3ZN5xvbA==' }).first + refute_nil r + assert_equal '1vw2LeZgjRXW1Z00Xi97WII5Tbh0ln3ZN5xvbA==', r['_id'] + assert_equal nil, r['emr_demographics_primary_key'] + assert_equal '91604', r['primary_care_provider_id'] + assert_equal "xwoDLIzZNOJEqsIyDZsEBKghaFCEBNJp8cHPBA==", r['medical_record_number'] + assert_equal "1Z7vtn07FWZ4ZF60j5gbmUm37T7YA1skM6ABwg==", r['first'] + assert_equal "55uSmm6sHs6+WtpNh8HLeESBMgT/e79yROoGyA==", r['last'] + assert_equal Time.gm(2011,4,9).to_i, r['birthdate'] + assert_equal "F", r['gender'] + performer = r['encounters'][0]['performer'] + assert_equal "", performer['given_name'] + # performer is anonymized + assert_equal "723CDj1qKtsyu1RWPnBZZ4xV+24qZMoEYh/BuQ==", performer['family_name'] + assert_equal performer['family_name'], performer['npi'] + end + end diff --git a/test/functional/results_controller_test.rb b/test/functional/results_controller_test.rb index 6a49889..b95d679 100644 --- a/test/functional/results_controller_test.rb +++ b/test/functional/results_controller_test.rb @@ -3,7 +3,7 @@ class ResultsControllerTest < ActionController::TestCase setup do dump_database - Factory(:gender_result) + FactoryGirl.create(:gender_result) end test "should get an atom feed at index" do diff --git a/test/functional/sysinfo_controller_test.rb b/test/functional/sysinfo_controller_test.rb new file mode 100644 index 0000000..93f2147 --- /dev/null +++ b/test/functional/sysinfo_controller_test.rb @@ -0,0 +1,34 @@ +require 'test_helper' + +class SysinfoControllerTest < ActionController::TestCase + test "should get currentload" do + get :currentload + assert_response :success + end + + test "should get currentusers" do + get :currentusers + assert_response :success + end + + test "should get diskspace" do + get :diskspace + assert_response :success + end + + test "should get mongo" do + get :mongo + assert_response :success + end + + test "should get totalprocesses" do + get :totalprocesses + assert_response :success + end + + test "should get swap" do + get :swap + assert_response :success + end + +end diff --git a/test/integration/.gitkeep b/test/integration/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/integration/importer/demographics_importer_api_test.rb b/test/integration/importer/demographics_importer_api_test.rb index 350e1f8..1657f46 100644 --- a/test/integration/importer/demographics_importer_api_test.rb +++ b/test/integration/importer/demographics_importer_api_test.rb @@ -11,4 +11,37 @@ def test_demographics_importing assert_equal 4, @context.eval('patient.birthtime().getUTCDate()') assert_equal 25, @context.eval('Math.floor(patient.age(sampleDate))') end +end + +class E2EDemographicsImporterApiTest < E2EImporterApiTest + def test_e2e_demographics_importing + assert_equal 'JOHN', @context.eval('e2e_patient.given()') + assert_equal 'CLEESE', @context.eval('e2e_patient.last()') + assert_equal 'M', @context.eval('e2e_patient.gender()') + assert_equal 1940, @context.eval('e2e_patient.birthtime().getUTCFullYear()') + # JS numbers months starting with 0, so 8 below is actually September as expected + assert_equal 8, @context.eval('e2e_patient.birthtime().getUTCMonth()') + assert_equal 25, @context.eval('e2e_patient.birthtime().getUTCDate()') + assert_equal 69, @context.eval('Math.floor(e2e_patient.age(sampleDate))') + # illustrate how to retrieve primary key of demographics table in EMR instance used to populate records collection + assert_equal "1", @context.eval('e2e_patient["json"]["emr_demographics_primary_key"]') + assert_equal "cpsid", @context.eval('e2e_patient["json"]["primary_care_provider_id"]') + end +end + +class E2EDemographicsImporterApiTest2 < E2EImporterApiTest2 + def test_e2e_demographics_importing_zarilla + assert_equal 'Melvin', @context.eval('e2e_patient2.given()') + assert_equal 'Zarilla', @context.eval('e2e_patient2.last()') + assert_equal 'F', @context.eval('e2e_patient2.gender()') + assert_equal 2011, @context.eval('e2e_patient2.birthtime().getUTCFullYear()') + # JS numbers months starting with 0, so 8 below is actually September as expected + assert_equal 3, @context.eval('e2e_patient2.birthtime().getUTCMonth()') + assert_equal 9, @context.eval('e2e_patient2.birthtime().getUTCDate()') + assert_equal 3, @context.eval('Math.floor(e2e_patient2.age(sampleDate))') + # illustrate how to retrieve primary key of demographics table in EMR instance used to populate records collection + # only works for Oscar E2E documents at moment so expect nil here + assert_equal nil, @context.eval('e2e_patient2["json"]["emr_demographics_primary_key"]') + assert_equal "91604", @context.eval('e2e_patient2["json"]["primary_care_provider_id"]') + end end \ No newline at end of file diff --git a/test/integration/importer/encounter_importer_api_test.rb b/test/integration/importer/encounter_importer_api_test.rb index 3c0876f..b48a1be 100644 --- a/test/integration/importer/encounter_importer_api_test.rb +++ b/test/integration/importer/encounter_importer_api_test.rb @@ -2,10 +2,12 @@ class EncounterImporterApiTest < ImporterApiTest def test_encounter_importing + #assert_equal 'xyz', @context.eval('patient.encounters()') assert_equal 1, @context.eval('patient.encounters().length') assert @context.eval('patient.encounters().match({"CPT": ["99241"]}).length != 0') # TODO Need to update the patientapi to handle performer now that they are no longer embedded # assert_equal 'Dr. Kildare', @context.eval('patient.encounters()[0].performer().person().name()') + #assert_equal nil, @context.eval('patient.encounters()[0].performer().person()') assert_equal 'Good Health Clinic', @context.eval('patient.encounters()[0].facility().name()') assert @context.eval('patient.encounters()[0].reasonForVisit().includesCodeFrom({"SNOMED-CT": ["308292007"]})') assert @context.eval('patient.encounters()[0].admitType().includedIn({"CPT": ["xyzzy"]})') @@ -13,4 +15,59 @@ def test_encounter_importing assert_equal 3, @context.eval('patient.encounters()[0].date().getUTCMonth()') assert_equal 7, @context.eval('patient.encounters()[0].date().getUTCDate()') end -end \ No newline at end of file +end + +class E2EEncounterImporterApiTest < E2EImporterApiTest + def test_e2e_encounter_importing + assert_equal 6, @context.eval('e2e_patient.encounters().length') + #TODO provide a nicer way to get performer information + #TODO consider reverting encounter provider to a hash field as it existed when patientapi was last maintained + assert_equal '', @context.eval('e2e_patient.encounters()[0].performer()["json"]["given_name"]') + family_name=@context.eval('e2e_patient.encounters()[0].performer()["json"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal family_name, @context.eval('e2e_patient.encounters()[0].performer()["json"]["npi"]') + #assert_equal 'doctor', @context.eval('e2e_patient.encounters()[0].performer()["json"]["given_name"]') + #assert_equal 'oscardoc', @context.eval('e2e_patient.encounters()[0].performer()["json"]["family_name"]') + #assert_equal 'cpsid', @context.eval('e2e_patient.encounters()[0].performer()["json"]["npi"]') + #Note that provider time resolved to midnight plus 7 hours (i.e., UTC midnight) before DateTime was substituted for Date in HDS E2E provider importer + #assert_equal 'xyz', @context.eval('e2e_patient.encounters()[0]') + assert_equal Time.gm(2013,9,25,15,50,0).to_i, @context.eval('e2e_patient.encounters()[0].performer()["json"]["start"]') + assert_equal Time.gm(2013,9,25,15,50,0).to_i, @context.eval('e2e_patient.encounters()[0]["json"]["start_time"]') + assert_equal Time.gm(2013,9,25,15,50,0).to_i, @context.eval('e2e_patient.encounters()[0].startDate()').to_i + assert_nil @context.eval('e2e_patient.encounters()[0].facility()') + assert @context.eval('e2e_patient.encounters()[0].reasonForVisit().includesCodeFrom({"ObservationType-CA-Pending": ["REASON"]})') + assert_nil @context.eval('e2e_patient.encounters()[0].admitType()') + assert_equal 2013, @context.eval('e2e_patient.encounters()[0].startDate().getUTCFullYear()') + # Note month count is 0 through 11 so 8 is actually September. + assert_equal 8, @context.eval('e2e_patient.encounters()[0].startDate().getUTCMonth()') + assert_equal 25, @context.eval('e2e_patient.encounters()[0].startDate().getUTCDate()') + end +end + +class E2EEncounterImporterApiTest2 < E2EImporterApiTest2 + def test_e2e_encounter_importing_zarilla + assert_equal 3, @context.eval('e2e_patient2.encounters().length') + #TODO provide a nicer way to get performer information + #TODO consider reverting encounter provider to a hash field as it existed when patientapi was last maintained + assert_equal '', @context.eval('e2e_patient2.encounters()[0].performer()["json"]["given_name"]') + family_name0=@context.eval('e2e_patient2.encounters()[0].performer()["json"]["family_name"]') + family_name1=@context.eval('e2e_patient2.encounters()[1].performer()["json"]["family_name"]') + family_name2=@context.eval('e2e_patient2.encounters()[2].performer()["json"]["family_name"]') + assert_equal '723CDj1qKtsyu1RWPnBZZ4xV+24qZMoEYh/BuQ==', family_name0 + assert_equal '723CDj1qKtsyu1RWPnBZZ4xV+24qZMoEYh/BuQ==', family_name1 + assert_equal 'uEFPPUFw3c7CDbHqEc96WJlAffuarPOnsUFbnw==', family_name2 + assert_equal family_name0, @context.eval('e2e_patient2.encounters()[0].performer()["json"]["npi"]') + #Note that provider time resolved to midnight plus 7 hours (i.e., UTC midnight) before DateTime was substituted for Date in HDS E2E provider importer + #assert_equal 'xyz', @context.eval('e2e_patient2.encounters()[0]') + assert_equal Time.gm(2012,6,12,10,0,0).to_i, @context.eval('e2e_patient2.encounters()[0].performer()["json"]["start"]') + assert_equal Time.gm(2012,6,12,10,0,0).to_i, @context.eval('e2e_patient2.encounters()[0]["json"]["start_time"]') + assert_equal Time.gm(2012,6,12,10,0,0).to_i, @context.eval('e2e_patient2.encounters()[0].startDate()').to_i + assert_nil @context.eval('e2e_patient2.encounters()[0].facility()') + assert @context.eval('e2e_patient2.encounters()[0].reasonForVisit().includesCodeFrom({"ObservationType-CA-Pending": ["REASON"]})') + assert_nil @context.eval('e2e_patient2.encounters()[0].admitType()') + assert_equal 2012, @context.eval('e2e_patient2.encounters()[0].startDate().getUTCFullYear()') + # Note month count is 0 through 11 so 8 is actually September. + assert_equal 5, @context.eval('e2e_patient2.encounters()[0].startDate().getUTCMonth()') + assert_equal 12, @context.eval('e2e_patient2.encounters()[0].startDate().getUTCDate()') + end +end diff --git a/test/integration/importer/immunizations_importer_api_test.rb b/test/integration/importer/immunizations_importer_api_test.rb index e1a248a..de4265f 100644 --- a/test/integration/importer/immunizations_importer_api_test.rb +++ b/test/integration/importer/immunizations_importer_api_test.rb @@ -26,4 +26,60 @@ def test_imunizations_importing assert_equal 'CVX', @context.eval('patient.immunizations()[3].medicationInformation().codedProduct()[1].codeSystemName()') assert_equal '113', @context.eval('patient.immunizations()[3].medicationInformation().codedProduct()[1].code()') end +end + +class E2EImmunizationsImporterApiTest < E2EImporterApiTest + def test_e2e_imunizations_importing + assert_equal 3, @context.eval('e2e_patient.immunizations().length') + assert @context.eval('e2e_patient.immunizations().match({"whoATC": ["J07CA01"]}).length != 0') + assert @context.eval('e2e_patient.immunizations().match({"whoATC": ["J07AL02"]}, null, null, true).length != 0') + assert @context.eval('e2e_patient.immunizations().match({"whoATC": ["J07BB01"]}, null, null, true).length != 0') +# TODO Need to update the patientapi to handle performer now that they are no longer embedded +# assert_equal 'FirstName', @context.eval('e2e_patient.immunizations()[3].performer().person().given()') +# assert_equal 'LastName', @context.eval('e2e_patient.immunizations()[3].performer().person().last()') +# assert_equal 1, @context.eval('e2e_patient.immunizations()[3].performer().person().addresses().length') +# assert_equal '100 Bureau Drive', @context.eval('e2e_patient.immunizations()[3].performer().person().addresses()[0].street()[0]') +# assert_equal 'Gaithersburg', @context.eval('e2e_patient.immunizations()[3].performer().person().addresses()[0].city()') +# assert_equal 'MD', @context.eval('e2e_patient.immunizations()[3].performer().person().addresses()[0].state()') +# assert_equal '20899', @context.eval('e2e_patient.immunizations()[3].performer().person().addresses()[0].postalCode()') + assert_equal nil, @context.eval('e2e_patient.immunizations()[2].refusalInd()') + assert_equal false, @context.eval('e2e_patient.immunizations()[2].refusalReason().isPatObj()') + assert_equal 2012, @context.eval('e2e_patient.immunizations()[0].startDate().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.immunizations()[0].startDate().getUTCMonth()') + assert_equal 1, @context.eval('e2e_patient.immunizations()[0].startDate().getUTCDate()') + assert @context.eval('e2e_patient.immunizations()[0].includesCodeFrom({"whoATC": ["J07CA01"]})') + assert @context.eval('e2e_patient.immunizations()[2].includesCodeFrom({"whoATC": ["J07AL02"]})') + #TODO find out why these methods don't work (claims codeSystemName is undefined) + #assert_equal 'xyz', @context.eval('e2e_patient.immunizations()[0].medicationInformation().codedProduct()[0]') + #assert_equal 'whoATC', @context.eval('e2e_patient.immunizations()[0].medicationInformation().codedProduct()[0].codeSystemName()') + #assert_equal 'J07CA01', @context.eval('e2e_patient.immunizations()[0].medicationInformation().codedProduct()[0].code()') + #assert_equal 'whoATC', @context.eval('e2e_patient.immunizations()[2].medicationInformation().codedProduct()[1].codeSystemName()') + #assert_equal 'J07AL02', @context.eval('e2e_patient.immunizations()[2].medicationInformation().codedProduct()[1].code()') + + end +end + + +class E2EImmunizationsImporterApiTest2 < E2EImporterApiTest2 + def test_e2e_imunizations_importing_zarilla + assert_equal 3, @context.eval('e2e_patient2.immunizations().length') + assert @context.eval('e2e_patient2.immunizations().match({"Unknown": ["NA"]}).length != 0') + assert @context.eval('e2e_patient2.immunizations().match({"Unknown": ["NA"]}, null, null, true).length != 0') +# TODO Need to update the patientapi to handle performer now that they are no longer embedded +# assert_equal 'FirstName', @context.eval('e2e_patient2.immunizations()[3].performer().person().given()') +# assert_equal 'LastName', @context.eval('e2e_patient2.immunizations()[3].performer().person().last()') +# assert_equal 1, @context.eval('e2e_patient2.immunizations()[3].performer().person().addresses().length') +# assert_equal '100 Bureau Drive', @context.eval('e2e_patient2.immunizations()[3].performer().person().addresses()[0].street()[0]') +# assert_equal 'Gaithersburg', @context.eval('e2e_patient2.immunizations()[3].performer().person().addresses()[0].city()') +# assert_equal 'MD', @context.eval('e2e_patient2.immunizations()[3].performer().person().addresses()[0].state()') +# assert_equal '20899', @context.eval('e2e_patient2.immunizations()[3].performer().person().addresses()[0].postalCode()') + assert_equal nil, @context.eval('e2e_patient2.immunizations()[2].refusalInd()') + assert_equal false, @context.eval('e2e_patient2.immunizations()[2].refusalReason().isPatObj()') + assert_equal 2012, @context.eval('e2e_patient2.immunizations()[0].date().getUTCFullYear()') + assert_equal 3, @context.eval('e2e_patient2.immunizations()[0].date().getUTCMonth()') + assert_equal 17, @context.eval('e2e_patient2.immunizations()[0].date().getUTCDate()') + assert @context.eval('e2e_patient2.immunizations()[0].includesCodeFrom({"Unknown": ["NA"]})') + assert_equal 'Varicella Zoster', @context.eval('e2e_patient2.immunizations()[2]["json"]["description"]') + + end end \ No newline at end of file diff --git a/test/integration/importer/medications_importer_api_test.rb b/test/integration/importer/medications_importer_api_test.rb index 2e2d135..14ca5de 100644 --- a/test/integration/importer/medications_importer_api_test.rb +++ b/test/integration/importer/medications_importer_api_test.rb @@ -38,4 +38,360 @@ def test_medications_importing assert_equal nil, @context.eval('patient.medications()[0].fulfillmentHistory()[0].quantityDispensed().unit()') assert_equal 4, @context.eval('patient.medications()[0].fulfillmentHistory()[0].fillNumber()') end -end \ No newline at end of file +end + + +class E2EMedicationsImporterApiTest < E2EImporterApiTest + def test_e2e_medications_importing + assert_equal 9, @context.eval('e2e_patient.medications().length') + assert @context.eval('e2e_patient.medications().match({"HC-DIN": ["00559407"]})') + assert @context.eval('e2e_patient.medications().match({"whoATC": ["N02BE01"]}).length != 0') + #assert_equal "xyz", @context.eval('e2e_patient.medications()') + #assert_equal 2, @context.eval('e2e_patient.medications()[0].dose().value()') + #assert_equal nil, @context.eval('e2e_patient.medications()[0].dose().unit()') + + #1st + assert_equal true, @context.eval('e2e_patient.medications()[0].includesCodeFrom({"HC-DIN": ["00559407"]})') + assert_equal true, @context.eval('e2e_patient.medications()[0].includesCodeFrom({"whoATC": ["N02BE01"]})') + assert_equal ' E2E_PRN_FLAG E2E_LONG_TERM_FLAG', @context.eval('e2e_patient.medications()[0].freeTextSig()') + assert_equal true, @context.eval('e2e_patient.medications()[0].isPRN()') + assert_equal true, @context.eval('e2e_patient.medications()[0].isLongTerm()') + # test importing of medication strengths + assert_equal 1, @context.eval('e2e_patient.medications()[0].values().length') + assert_equal 500, @context.eval('e2e_patient.medications()[0].values()[0].scalar()') + assert_equal 'MG', @context.eval('e2e_patient.medications()[0].values()[0].units()') + + assert_equal 'active', @context.eval('e2e_patient.medications()[0]["json"]["statusOfMedication"]["value"]') + + assert_equal 2013, @context.eval('e2e_patient.medications()[0].timeStamp().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.medications()[0].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient.medications()[0].timeStamp().getUTCDate()') + #TODO Provide patientapi with a frequency method + assert_equal 4, @context.eval('e2e_patient.medications()[0].administrationTiming()["json"]["frequency"]["numerator"]["value"]') + assert_equal nil, @context.eval('e2e_patient.medications()[0].administrationTiming()["json"]["frequency"]["numerator"]["unit"]') + assert_equal 1, @context.eval('e2e_patient.medications()[0].administrationTiming()["json"]["frequency"]["denominator"]["value"]') + assert_equal "d", @context.eval('e2e_patient.medications()[0].administrationTiming()["json"]["frequency"]["denominator"]["unit"]') + assert_equal nil, @context.eval('e2e_patient.medications()[0].administrationTiming().institutionSpecified()') + #TODO Determine why the code, codeSystemName, isPrescription, etc. are not available for E2E + assert_equal nil, @context.eval('e2e_patient.medications()[0].typeOfMedication().code()') + assert_equal nil, @context.eval('e2e_patient.medications()[0].typeOfMedication().codeSystemName()') + assert_equal false, @context.eval('e2e_patient.medications()[0].typeOfMedication().isPrescription()') + assert_equal false, @context.eval('e2e_patient.medications()[0].typeOfMedication().isOverTheCounter()') + #TODO Determine whether any of route, site, productForm, vehicle, deliveryMethod, + #TODO doseRestriction, or fulfillmentHistory can be supported + assert_equal 1, @context.eval('e2e_patient.medications()[0].orderInformation().length') + family_name = @context.eval('e2e_patient.medications()[0].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal '', @context.eval('e2e_patient.medications()[0].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient.medications()[0].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal Time.gm(2013,9,27).to_i, @context.eval('e2e_patient.medications()[0].orderInformation()[0].orderDateTime()').to_i + assert_equal true, @context.eval('e2e_patient.medications()[0].orderInformation()[0].isPRN()') + #2nd + assert_equal true, @context.eval('e2e_patient.medications()[1].includesCodeFrom({"HC-DIN": ["00613215"]})') + assert_equal true, @context.eval('e2e_patient.medications()[1].includesCodeFrom({"whoATC": ["C03DA01"]})') + assert_equal ' E2E_LONG_TERM_FLAG', @context.eval('e2e_patient.medications()[1].freeTextSig()') + assert_equal false, @context.eval('e2e_patient.medications()[1].isPRN()') + assert_equal true, @context.eval('e2e_patient.medications()[1].isLongTerm()') + assert_equal 1, @context.eval('e2e_patient.medications()[1].values().length') + assert_equal 25.0, @context.eval('e2e_patient.medications()[1].values()[0].scalar()') + assert_equal 'MG', @context.eval('e2e_patient.medications()[1].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient.medications()[1]["json"]["statusOfMedication"]["value"]') + assert_equal 2013, @context.eval('e2e_patient.medications()[1].timeStamp().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.medications()[1].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient.medications()[1].timeStamp().getUTCDate()') + assert_equal 1, @context.eval('e2e_patient.medications()[1].orderInformation().length') + family_name=@context.eval('e2e_patient.medications()[1].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal '', @context.eval('e2e_patient.medications()[1].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient.medications()[1].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal Time.gm(2013,9,27).to_i, @context.eval('e2e_patient.medications()[1].orderInformation()[0].orderDateTime()').to_i + assert_equal false, @context.eval('e2e_patient.medications()[1].orderInformation()[0].isPRN()') + + #3rd + assert_equal true, @context.eval('e2e_patient.medications()[2].includesCodeFrom({"HC-DIN": ["00636533"]})') + assert_equal true, @context.eval('e2e_patient.medications()[2].includesCodeFrom({"whoATC": ["M01AE01"]})') + assert_equal ' E2E_PRN_FLAG E2E_LONG_TERM_FLAG', @context.eval('e2e_patient.medications()[2].freeTextSig()') + assert_equal true, @context.eval('e2e_patient.medications()[2].isPRN()') + assert_equal true, @context.eval('e2e_patient.medications()[2].isLongTerm()') + assert_equal 1, @context.eval('e2e_patient.medications()[2].values().length') + assert_equal 400.0, @context.eval('e2e_patient.medications()[2].values()[0].scalar()') + assert_equal 'MG', @context.eval('e2e_patient.medications()[2].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient.medications()[2]["json"]["statusOfMedication"]["value"]') + assert_equal 2013, @context.eval('e2e_patient.medications()[2].timeStamp().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.medications()[2].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient.medications()[2].timeStamp().getUTCDate()') + assert_equal 1, @context.eval('e2e_patient.medications()[2].orderInformation().length') + family_name=@context.eval('e2e_patient.medications()[2].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal '', @context.eval('e2e_patient.medications()[2].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient.medications()[2].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal Time.gm(2013,9,27).to_i, @context.eval('e2e_patient.medications()[2].orderInformation()[0].orderDateTime()').to_i + assert_equal true, @context.eval('e2e_patient.medications()[2].orderInformation()[0].isPRN()') + + #4th + assert_equal true, @context.eval('e2e_patient.medications()[3].includesCodeFrom({"HC-DIN": ["02041421"]})') + assert_equal true, @context.eval('e2e_patient.medications()[3].includesCodeFrom({"whoATC": ["N05BA06"]})') + assert_equal ' E2E_PRN_FLAG E2E_LONG_TERM_FLAG', @context.eval('e2e_patient.medications()[3].freeTextSig()') + assert_equal true, @context.eval('e2e_patient.medications()[3].isPRN()') + assert_equal true, @context.eval('e2e_patient.medications()[3].isLongTerm()') + assert_equal 1, @context.eval('e2e_patient.medications()[3].values().length') + assert_equal 1.0, @context.eval('e2e_patient.medications()[3].values()[0].scalar()') + assert_equal 'MG', @context.eval('e2e_patient.medications()[3].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient.medications()[3]["json"]["statusOfMedication"]["value"]') + assert_equal 2013, @context.eval('e2e_patient.medications()[3].timeStamp().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.medications()[3].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient.medications()[3].timeStamp().getUTCDate()') + assert_equal 1, @context.eval('e2e_patient.medications()[3].orderInformation().length') + family_name=@context.eval('e2e_patient.medications()[3].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal '', @context.eval('e2e_patient.medications()[3].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient.medications()[3].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal Time.gm(2013,9,27).to_i, @context.eval('e2e_patient.medications()[3].orderInformation()[0].orderDateTime()').to_i + assert_equal true, @context.eval('e2e_patient.medications()[3].orderInformation()[0].isPRN()') + + #5th + assert_equal true, @context.eval('e2e_patient.medications()[4].includesCodeFrom({"HC-DIN": ["02244993"]})') + assert_equal true, @context.eval('e2e_patient.medications()[4].includesCodeFrom({"whoATC": ["B01AC06"]})') + assert_equal ' E2E_LONG_TERM_FLAG', @context.eval('e2e_patient.medications()[4].freeTextSig()') + assert_equal false, @context.eval('e2e_patient.medications()[4].isPRN()') + assert_equal true, @context.eval('e2e_patient.medications()[4].isLongTerm()') + assert_equal 1, @context.eval('e2e_patient.medications()[4].values().length') + assert_equal 81.0, @context.eval('e2e_patient.medications()[4].values()[0].scalar()') + assert_equal 'MG', @context.eval('e2e_patient.medications()[4].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient.medications()[4]["json"]["statusOfMedication"]["value"]') + assert_equal 2013, @context.eval('e2e_patient.medications()[4].timeStamp().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.medications()[4].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient.medications()[4].timeStamp().getUTCDate()') + assert_equal 1, @context.eval('e2e_patient.medications()[4].orderInformation().length') + family_name=@context.eval('e2e_patient.medications()[4].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal '', @context.eval('e2e_patient.medications()[4].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient.medications()[4].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal Time.gm(2013,9,27).to_i, @context.eval('e2e_patient.medications()[4].orderInformation()[0].orderDateTime()').to_i + assert_equal false, @context.eval('e2e_patient.medications()[4].orderInformation()[0].isPRN()') + + #6th + assert_equal true, @context.eval('e2e_patient.medications()[5].includesCodeFrom({"HC-DIN": ["02351420"]})') + assert_equal true, @context.eval('e2e_patient.medications()[5].includesCodeFrom({"whoATC": ["C03CA01"]})') + assert_equal ' E2E_LONG_TERM_FLAG', @context.eval('e2e_patient.medications()[5].freeTextSig()') + assert_equal false, @context.eval('e2e_patient.medications()[5].isPRN()') + assert_equal true, @context.eval('e2e_patient.medications()[5].isLongTerm()') + assert_equal 1, @context.eval('e2e_patient.medications()[5].values().length') + assert_equal 20.0, @context.eval('e2e_patient.medications()[5].values()[0].scalar()') + assert_equal 'MG', @context.eval('e2e_patient.medications()[5].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient.medications()[5]["json"]["statusOfMedication"]["value"]') + assert_equal 2013, @context.eval('e2e_patient.medications()[5].timeStamp().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.medications()[5].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient.medications()[5].timeStamp().getUTCDate()') + assert_equal 1, @context.eval('e2e_patient.medications()[5].orderInformation().length') + family_name=@context.eval('e2e_patient.medications()[5].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal '', @context.eval('e2e_patient.medications()[5].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient.medications()[5].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal Time.gm(2013,9,27).to_i, @context.eval('e2e_patient.medications()[5].orderInformation()[0].orderDateTime()').to_i + assert_equal false, @context.eval('e2e_patient.medications()[5].orderInformation()[0].isPRN()') + + #7th + assert_equal true, @context.eval('e2e_patient.medications()[6].includesCodeFrom({"HC-DIN": ["02363283"]})') + assert_equal true, @context.eval('e2e_patient.medications()[6].includesCodeFrom({"whoATC": ["C09AA05"]})') + assert_equal ' E2E_LONG_TERM_FLAG', @context.eval('e2e_patient.medications()[6].freeTextSig()') + assert_equal false, @context.eval('e2e_patient.medications()[6].isPRN()') + assert_equal true, @context.eval('e2e_patient.medications()[6].isLongTerm()') + assert_equal 1, @context.eval('e2e_patient.medications()[6].values().length') + assert_equal 5.0, @context.eval('e2e_patient.medications()[6].values()[0].scalar()') + assert_equal 'MG', @context.eval('e2e_patient.medications()[6].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient.medications()[6]["json"]["statusOfMedication"]["value"]') + assert_equal 2013, @context.eval('e2e_patient.medications()[6].timeStamp().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.medications()[6].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient.medications()[6].timeStamp().getUTCDate()') + assert_equal 1, @context.eval('e2e_patient.medications()[6].orderInformation().length') + family_name=@context.eval('e2e_patient.medications()[6].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal '', @context.eval('e2e_patient.medications()[6].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient.medications()[6].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal Time.gm(2013,9,27).to_i, @context.eval('e2e_patient.medications()[6].orderInformation()[0].orderDateTime()').to_i + assert_equal false, @context.eval('e2e_patient.medications()[6].orderInformation()[0].isPRN()') + + #8th + assert_equal true, @context.eval('e2e_patient.medications()[7].includesCodeFrom({"HC-DIN": ["02364948"]})') + assert_equal true, @context.eval('e2e_patient.medications()[7].includesCodeFrom({"whoATC": ["C07AG02"]})') + assert_equal ' E2E_LONG_TERM_FLAG', @context.eval('e2e_patient.medications()[7].freeTextSig()') + assert_equal false, @context.eval('e2e_patient.medications()[7].isPRN()') + assert_equal true, @context.eval('e2e_patient.medications()[7].isLongTerm()') + assert_equal 1, @context.eval('e2e_patient.medications()[7].values().length') + assert_equal 12.5, @context.eval('e2e_patient.medications()[7].values()[0].scalar()') + assert_equal 'MG', @context.eval('e2e_patient.medications()[7].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient.medications()[7]["json"]["statusOfMedication"]["value"]') + assert_equal 2013, @context.eval('e2e_patient.medications()[7].timeStamp().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.medications()[7].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient.medications()[7].timeStamp().getUTCDate()') + assert_equal 1, @context.eval('e2e_patient.medications()[7].orderInformation().length') + family_name=@context.eval('e2e_patient.medications()[7].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal '', @context.eval('e2e_patient.medications()[7].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient.medications()[7].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal Time.gm(2013,9,27).to_i, @context.eval('e2e_patient.medications()[7].orderInformation()[0].orderDateTime()').to_i + assert_equal false, @context.eval('e2e_patient.medications()[7].orderInformation()[0].isPRN()') + + #9th and last + assert_equal true, @context.eval('e2e_patient.medications()[8].includesCodeFrom({"HC-DIN": ["02387913"]})') + assert_equal true, @context.eval('e2e_patient.medications()[8].includesCodeFrom({"whoATC": ["C10AA05"]})') + assert_equal ' E2E_LONG_TERM_FLAG', @context.eval('e2e_patient.medications()[8].freeTextSig()') + assert_equal false, @context.eval('e2e_patient.medications()[8].isPRN()') + assert_equal true, @context.eval('e2e_patient.medications()[8].isLongTerm()') + assert_equal 1, @context.eval('e2e_patient.medications()[8].values().length') + assert_equal 40, @context.eval('e2e_patient.medications()[8].values()[0].scalar()') + assert_equal 'MG', @context.eval('e2e_patient.medications()[8].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient.medications()[8]["json"]["statusOfMedication"]["value"]') + assert_equal 2013, @context.eval('e2e_patient.medications()[8].timeStamp().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.medications()[8].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient.medications()[8].timeStamp().getUTCDate()') + assert_equal 1, @context.eval('e2e_patient.medications()[8].orderInformation().length') + family_name= @context.eval('e2e_patient.medications()[8].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal 'qbGJGxVjhsCx/JR42Bd7tX4nbBYNgR/TehN7gQ==', family_name + assert_equal '', @context.eval('e2e_patient.medications()[8].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient.medications()[8].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal Time.gm(2013,9,27).to_i, @context.eval('e2e_patient.medications()[8].orderInformation()[0].orderDateTime()').to_i + assert_equal false, @context.eval('e2e_patient.medications()[8].orderInformation()[0].isPRN()') + + end +end + + + +class E2EMedicationsImporterApiTest2 < E2EImporterApiTest2 + def test_e2e_medications_importing_zarilla + assert_equal 7, @context.eval('e2e_patient2.medications().length') + assert @context.eval('e2e_patient2.medications().match({"HC-DIN": ["2139324"]})') + assert @context.eval('e2e_patient2.medications().match({"whoATC": ["N02BE01"]}).length == 0') + + # test importing of medication strengths, prescription date, instructions to patient + #1st + assert_equal true, @context.eval('e2e_patient2.medications()[0].includesCodeFrom({"HC-DIN": ["2241497"]})') + assert_equal true, @context.eval('e2e_patient2.medications()[0].includesCodeFrom({"whoATC": ["R03AC02"]})') + assert_equal 1, @context.eval('e2e_patient2.medications()[0].values().length') + assert_equal 100, @context.eval('e2e_patient2.medications()[0].values()[0].scalar()') + assert_equal 'Mcg', @context.eval('e2e_patient2.medications()[0].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient2.medications()[0]["json"]["statusOfMedication"]["value"]') + assert_equal Time.gm(2013,11,6), @context.eval('e2e_patient2.medications()[0].timeStamp()') + assert_equal 2013, @context.eval('e2e_patient2.medications()[0].timeStamp().getUTCFullYear()') + assert_equal 10, @context.eval('e2e_patient2.medications()[0].timeStamp().getUTCMonth()') + assert_equal 6, @context.eval('e2e_patient2.medications()[0].timeStamp().getUTCDate()') + assert_equal 1, @context.eval('e2e_patient2.medications()[0].orderInformation().length') + assert_equal '[Frequency: Four times daily]', @context.eval('e2e_patient2.medications()[0].administrationTiming()["json"]["text"]') + assert_equal '1-2 Puffs four times daily for 30 days. Use with Aerochamber', @context.eval('e2e_patient2.medications()[0].freeTextSig()') + assert_equal false, @context.eval('e2e_patient2.medications()[0].isPRN()') + assert_equal nil, @context.eval('e2e_patient2.medications()[0].isLongTerm()') + #No useful provider information in this document, Family name is hash of empty string. + family_name = @context.eval('e2e_patient2.medications()[0].orderInformation()[0]["json"]["performer"]["family_name"]') + assert_equal '0UoCjCo6K8lHYQK7KII0xBWisB+CjqYqxbPkLw==', family_name + assert_equal '', @context.eval('e2e_patient2.medications()[0].orderInformation()[0]["json"]["performer"]["given_name"]') + assert_equal family_name, @context.eval('e2e_patient2.medications()[0].orderInformation()[0]["json"]["performer"]["npi"]') + assert_equal nil, @context.eval('e2e_patient2.medications()[0].orderInformation()[0]["json"]["performer"]["start"]') + assert_equal false, @context.eval('e2e_patient2.medications()[0].orderInformation()[0].isPRN()') + + #2nd + assert_equal true, @context.eval('e2e_patient2.medications()[1].includesCodeFrom({"HC-DIN": ["682020"]})') + assert_equal true, @context.eval('e2e_patient2.medications()[1].includesCodeFrom({"whoATC": ["J01FA01"]})') + assert_equal 1, @context.eval('e2e_patient2.medications()[1].values().length') + assert_equal 1, @context.eval('e2e_patient2.medications()[1].values()[0].scalar()') + assert_equal 'Tablet(s)', @context.eval('e2e_patient2.medications()[1].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient2.medications()[1]["json"]["statusOfMedication"]["value"]') + assert_equal 'Take with Food', @context.eval('e2e_patient2.medications()[1].freeTextSig()') + assert_equal false, @context.eval('e2e_patient2.medications()[1].isPRN()') + assert_equal nil, @context.eval('e2e_patient2.medications()[1].isLongTerm()') + assert_equal Time.gm(2014,2,13), @context.eval('e2e_patient2.medications()[1].timeStamp()') + assert_equal 2014, @context.eval('e2e_patient2.medications()[1].timeStamp().getUTCFullYear()') + assert_equal 1, @context.eval('e2e_patient2.medications()[1].timeStamp().getUTCMonth()') + assert_equal 13, @context.eval('e2e_patient2.medications()[1].timeStamp().getUTCDate()') + assert_equal '[Frequency: Four times daily]', @context.eval('e2e_patient2.medications()[1].administrationTiming()["json"]["text"]') + assert_equal false, @context.eval('e2e_patient2.medications()[1].orderInformation()[0].isPRN()') + + #3rd + assert_equal true, @context.eval('e2e_patient2.medications()[2].includesCodeFrom({"Unknown": ["NI"]})') + assert_equal 1, @context.eval('e2e_patient2.medications()[2].values().length') + assert_equal 5, @context.eval('e2e_patient2.medications()[2].values()[0].scalar()') + assert_equal 'Mg', @context.eval('e2e_patient2.medications()[2].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient2.medications()[2]["json"]["statusOfMedication"]["value"]') + assert_equal 'One capsule daily at bedtime as needed +. Take at bedtime E2E_PRN_FLAG', @context.eval('e2e_patient2.medications()[2].freeTextSig()') + assert_equal true, @context.eval('e2e_patient2.medications()[2].isPRN()') + assert_equal nil, @context.eval('e2e_patient2.medications()[2].isLongTerm()') + assert_equal Time.gm(2014,2,4), @context.eval('e2e_patient2.medications()[2].timeStamp()') + assert_equal 2014, @context.eval('e2e_patient2.medications()[2].timeStamp().getUTCFullYear()') + assert_equal 1, @context.eval('e2e_patient2.medications()[2].timeStamp().getUTCMonth()') + assert_equal 4, @context.eval('e2e_patient2.medications()[2].timeStamp().getUTCDate()') + assert_equal '[Frequency: Once daily]', @context.eval('e2e_patient2.medications()[2].administrationTiming()["json"]["text"]') + assert_equal true, @context.eval('e2e_patient2.medications()[2].orderInformation()[0].isPRN()') + + #4th + assert_equal true, @context.eval('e2e_patient2.medications()[3].includesCodeFrom({"HC-DIN": ["2243224"]})') + assert_equal true, @context.eval('e2e_patient2.medications()[3].includesCodeFrom({"whoATC": ["Unknown"]})') + assert_equal 1, @context.eval('e2e_patient2.medications()[3].values().length') + assert_equal 125, @context.eval('e2e_patient2.medications()[3].values()[0].scalar()') + assert_equal 'Mg', @context.eval('e2e_patient2.medications()[3].values()[0].units()') + assert_equal 'completed', @context.eval('e2e_patient2.medications()[3]["json"]["statusOfMedication"]["value"]') + assert_equal '125mg (5ml) three times daily +. Shake well before use and take until finished', @context.eval('e2e_patient2.medications()[3].freeTextSig()') + assert_equal false, @context.eval('e2e_patient2.medications()[3].isPRN()') + assert_equal nil, @context.eval('e2e_patient2.medications()[3].isLongTerm()') + assert_equal Time.gm(2014,2,27), @context.eval('e2e_patient2.medications()[3].timeStamp()') + assert_equal 2014, @context.eval('e2e_patient2.medications()[3].timeStamp().getUTCFullYear()') + assert_equal 1, @context.eval('e2e_patient2.medications()[3].timeStamp().getUTCMonth()') + assert_equal 27, @context.eval('e2e_patient2.medications()[3].timeStamp().getUTCDate()') + assert_equal '[Frequency: Three times daily]', @context.eval('e2e_patient2.medications()[3].administrationTiming()["json"]["text"]') + assert_equal false, @context.eval('e2e_patient2.medications()[3].orderInformation()[0].isPRN()') + + #5th + assert_equal true, @context.eval('e2e_patient2.medications()[4].includesCodeFrom({"HC-DIN": ["2139324"]})') + assert_equal true, @context.eval('e2e_patient2.medications()[4].includesCodeFrom({"whoATC": ["Unknown"]})') + assert_equal 1, @context.eval('e2e_patient2.medications()[4].values().length') + assert_equal 1, @context.eval('e2e_patient2.medications()[4].values()[0].scalar()') + assert_equal 'Millilitres', @context.eval('e2e_patient2.medications()[4].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient2.medications()[4]["json"]["statusOfMedication"]["value"]') + assert_equal '1ml with 5ml Normal saline by Nebulizer twice daily.', @context.eval('e2e_patient2.medications()[4].freeTextSig()') + assert_equal false, @context.eval('e2e_patient2.medications()[4].isPRN()') + assert_equal nil, @context.eval('e2e_patient2.medications()[4].isLongTerm()') + assert_equal Time.gm(2014,1,5), @context.eval('e2e_patient2.medications()[4].timeStamp()') + assert_equal 2014, @context.eval('e2e_patient2.medications()[4].timeStamp().getUTCFullYear()') + assert_equal 0, @context.eval('e2e_patient2.medications()[4].timeStamp().getUTCMonth()') + assert_equal 5, @context.eval('e2e_patient2.medications()[4].timeStamp().getUTCDate()') + assert_equal '[Frequency: Twice daily]', @context.eval('e2e_patient2.medications()[4].administrationTiming()["json"]["text"]') + assert_equal false, @context.eval('e2e_patient2.medications()[4].orderInformation()[0].isPRN()') + + #6th + assert_equal true, @context.eval('e2e_patient2.medications()[5].includesCodeFrom({"HC-DIN": ["1999761"]})') + assert_equal true, @context.eval('e2e_patient2.medications()[5].includesCodeFrom({"whoATC": ["H02AB08"]})') + assert_equal 1, @context.eval('e2e_patient2.medications()[5].values().length') + assert_equal 5, @context.eval('e2e_patient2.medications()[5].values()[0].scalar()') + assert_equal 'Mg', @context.eval('e2e_patient2.medications()[5].values()[0].units()') + assert_equal 'active', @context.eval('e2e_patient2.medications()[5]["json"]["statusOfMedication"]["value"]') + assert_equal '5mg administered intra-articularly to right foot monthly. Bring medication to Doctor\'s office for administration.', @context.eval('e2e_patient2.medications()[5].freeTextSig()') + assert_equal false, @context.eval('e2e_patient2.medications()[5].isPRN()') + assert_equal nil, @context.eval('e2e_patient2.medications()[5].isLongTerm()') + assert_equal Time.gm(2014,2,4), @context.eval('e2e_patient2.medications()[5].timeStamp()') + assert_equal 2014, @context.eval('e2e_patient2.medications()[5].timeStamp().getUTCFullYear()') + assert_equal 1, @context.eval('e2e_patient2.medications()[5].timeStamp().getUTCMonth()') + assert_equal 4, @context.eval('e2e_patient2.medications()[5].timeStamp().getUTCDate()') + assert_equal '[Frequency: Once a month]', @context.eval('e2e_patient2.medications()[5].administrationTiming()["json"]["text"]') + assert_equal false, @context.eval('e2e_patient2.medications()[5].orderInformation()[0].isPRN()') + + #7th + assert_equal true, @context.eval('e2e_patient2.medications()[6].includesCodeFrom({"HC-DIN": ["2273950"]})') + assert_equal true, @context.eval('e2e_patient2.medications()[6].includesCodeFrom({"whoATC": ["N06BA04"]})') + assert_equal 1, @context.eval('e2e_patient2.medications()[6].values().length') + assert_equal 5, @context.eval('e2e_patient2.medications()[6].values()[0].scalar()') + assert_equal 'Mg', @context.eval('e2e_patient2.medications()[6].values()[0].units()') + assert_equal 'completed', @context.eval('e2e_patient2.medications()[6]["json"]["statusOfMedication"]["value"]') + assert_equal '5mg twice daily.', @context.eval('e2e_patient2.medications()[6].freeTextSig()') + assert_equal false, @context.eval('e2e_patient2.medications()[6].isPRN()') + assert_equal nil, @context.eval('e2e_patient2.medications()[6].isLongTerm()') + assert_equal Time.gm(2013,12,6), @context.eval('e2e_patient2.medications()[6].timeStamp()') + assert_equal 2013, @context.eval('e2e_patient2.medications()[6].timeStamp().getUTCFullYear()') + assert_equal 11, @context.eval('e2e_patient2.medications()[6].timeStamp().getUTCMonth()') + assert_equal 6, @context.eval('e2e_patient2.medications()[6].timeStamp().getUTCDate()') + assert_equal '[Frequency: Twice daily]', @context.eval('e2e_patient2.medications()[6].administrationTiming()["json"]["text"]') + assert_equal false, @context.eval('e2e_patient2.medications()[6].orderInformation()[0].isPRN()') + + end +end diff --git a/test/integration/importer/procedure_importer_api_test.rb b/test/integration/importer/procedure_importer_api_test.rb index ee9dbcc..6750161 100644 --- a/test/integration/importer/procedure_importer_api_test.rb +++ b/test/integration/importer/procedure_importer_api_test.rb @@ -4,7 +4,7 @@ class ProcedureImporterApiTest < ImporterApiTest def test_procedure_importing assert_equal '52734007', @context.eval('patient.procedures()[0].type()[0].code()') assert_equal 'SNOMED-CT', @context.eval('patient.procedures()[0].type()[0].codeSystemName()') - assert_not_equal nil, @context.eval('patient.procedures()[0].performer()') + assert_equal nil, @context.eval('patient.procedures()[0].performer()') assert_equal '1234567', @context.eval('patient.procedures()[0].site().code()') assert_equal 'SNOMED-CT', @context.eval('patient.procedures()[0].site().codeSystemName()') end diff --git a/test/integration/importer/results_importer_api_test.rb b/test/integration/importer/results_importer_api_test.rb index cd3d7f9..66c7790 100644 --- a/test/integration/importer/results_importer_api_test.rb +++ b/test/integration/importer/results_importer_api_test.rb @@ -2,14 +2,49 @@ class ResultsImporterApiTest < ImporterApiTest def test_results_importing + assert_equal 6, @context.eval('patient.results().length') assert_equal '30313-1', @context.eval('patient.results()[0].type()[0].code()') assert_equal 'LOINC', @context.eval('patient.results()[0].type()[0].codeSystemName()') assert_equal 'N', @context.eval('patient.results()[0].interpretation().code()') assert_equal 'HITSP C80 Observation Status', @context.eval('patient.results()[0].interpretation().codeSystemName()') - assert_equal '13.2', @context.eval('patient.results()[0].values()[0].scalar()') + assert_equal 13.2, @context.eval('patient.results()[0].values()[0].scalar()') assert_equal 'g/dl', @context.eval('patient.results()[0].values()[0].units()') assert_equal 2000, @context.eval('patient.results()[0].date().getUTCFullYear()') assert_equal 2, @context.eval('patient.results()[0].date().getUTCMonth()') assert_equal 23, @context.eval('patient.results()[0].date().getUTCDate()') end -end \ No newline at end of file +end + +class E2EResultsImporterApiTest < E2EImporterApiTest + def test_e2e_results_importing + assert_equal 28, @context.eval('e2e_patient.results().length') + assert_equal '6690-2', @context.eval('e2e_patient.results()[0].type()[0].code()') + assert_equal 'pCLOCD', @context.eval('e2e_patient.results()[0].type()[0].codeSystemName()') + assert_equal 'N', @context.eval('e2e_patient.results()[0].interpretation().code()') + assert_equal 'ObservationInterpretation', @context.eval('e2e_patient.results()[0].interpretation().codeSystemName()') + assert_equal 8, @context.eval('e2e_patient.results()[0].values()[0].scalar()') + assert_equal 'giga/L', @context.eval('e2e_patient.results()[0].values()[0].units()') + assert_equal 2013, @context.eval('e2e_patient.results()[0].startDate().getUTCFullYear()') + assert_equal 4, @context.eval('e2e_patient.results()[0].startDate().getUTCMonth()') + assert_equal 31, @context.eval('e2e_patient.results()[0].startDate().getUTCDate()') + end +end + + +class E2EResultsImporterApiTest2 < E2EImporterApiTest2 + def test_e2e_results_importing_zarilla + #HDS testing reports 59 results but only 58 are seen here, presumably because of the one + #nullFlavor lab result observed. + assert_equal 58, @context.eval('e2e_patient2.results().length') + assert_equal '14771-0', @context.eval('e2e_patient2.results()[15].type()[0].code()') + assert_equal 'pCLOCD', @context.eval('e2e_patient2.results()[15].type()[0].codeSystemName()') + assert_equal 'N', @context.eval('e2e_patient2.results()[15].interpretation().code()') + assert_equal 'HITSP C80 Observation Status', @context.eval('e2e_patient2.results()[15].interpretation().codeSystemName()') + assert_equal 0, @context.eval('e2e_patient2.results()[15].values().length') + assert_equal '4.8 mmol/L', @context.eval('e2e_patient2.results()[15]["json"]["free_text"]') + assert_equal Time.gm(2012,3,12,17,50,6), @context.eval('e2e_patient2.results()[15].startDate()') + assert_equal 2012, @context.eval('e2e_patient2.results()[15].startDate().getUTCFullYear()') + assert_equal 2, @context.eval('e2e_patient2.results()[15].startDate().getUTCMonth()') + assert_equal 12, @context.eval('e2e_patient2.results()[15].startDate().getUTCDate()') + end +end diff --git a/test/integration/importer/vitals_importer_api_test.rb b/test/integration/importer/vitals_importer_api_test.rb index 1be3a98..c2e6875 100644 --- a/test/integration/importer/vitals_importer_api_test.rb +++ b/test/integration/importer/vitals_importer_api_test.rb @@ -1,15 +1,49 @@ require 'test_helper' class VitalsImporterApiTest < ImporterApiTest - def test_vitals_importing + def test_vitals_importing_c32 + assert_equal 5, @context.eval('patient.vitalSigns().length') assert @context.eval('patient.vitalSigns().match({"LOINC": ["8302-2"]}).length != 0') assert @context.eval('patient.vitalSigns().match({"SNOMED-CT": ["50373000"]}).length != 0') assert_equal 'N', @context.eval('patient.vitalSigns()[0].interpretation().code()') assert_equal 'HITSP C80 Observation Status', @context.eval('patient.vitalSigns()[0].interpretation().codeSystemName()') - assert_equal '177', @context.eval('patient.vitalSigns()[0].values()[0].scalar()') + assert_equal 177, @context.eval('patient.vitalSigns()[0].values()[0].scalar()') assert_equal 'cm', @context.eval('patient.vitalSigns()[0].values()[0].units()') assert_equal 1999, @context.eval('patient.vitalSigns()[0].date().getUTCFullYear()') assert_equal 10, @context.eval('patient.vitalSigns()[0].date().getUTCMonth()') assert_equal 14, @context.eval('patient.vitalSigns()[0].date().getUTCDate()') end -end \ No newline at end of file +end + +class E2EVitalsImporterApiTest < E2EImporterApiTest + def test_e2e_vitals_importing + #assert_equal 'theValue', @context.eval('e2e_patient.vitalSigns()') + assert_equal 7, @context.eval('e2e_patient.vitalSigns().length') + assert @context.eval('e2e_patient.vitalSigns().match({"LOINC": ["8480-6"]}).length != 0') + assert @context.eval('e2e_patient.vitalSigns().match({"LOINC": ["3141-9"]}).length != 0') + assert_equal 'Systolic Blood Pressure (sitting position)', @context.eval('e2e_patient.vitalSigns()[0].freeTextType()') + assert_equal 130, @context.eval('e2e_patient.vitalSigns()[0].values()[0].scalar()') + assert_equal 'mm[Hg]', @context.eval('e2e_patient.vitalSigns()[0].values()[0].units()') + assert_equal Time.gm(2013,9,25), @context.eval('e2e_patient.vitalSigns()[0].startDate()') + assert_equal 2013, @context.eval('e2e_patient.vitalSigns()[0].startDate().getUTCFullYear()') + assert_equal 8, @context.eval('e2e_patient.vitalSigns()[0].startDate().getUTCMonth()') + assert_equal 25, @context.eval('e2e_patient.vitalSigns()[0].startDate().getUTCDate()') + assert_nil @context.eval('e2e_patient.vitalSigns()[0].interpretation()') + end +end + +class E2EVitalsImporterApiTest2 < E2EImporterApiTest2 + def test_e2e_vitals_importing_zarilla + assert_equal 7, @context.eval('e2e_patient2.vitalSigns().length') + assert @context.eval('e2e_patient2.vitalSigns().match({"LOINC": ["8480-6"]}).length != 0') + assert @context.eval('e2e_patient2.vitalSigns().match({"LOINC": ["3141-9"]}).length != 0') + assert_equal 'Body height', @context.eval('e2e_patient2.vitalSigns()[0].freeTextType()') + assert_equal 82.5, @context.eval('e2e_patient2.vitalSigns()[0].values()[0].scalar()') + assert_equal 'cm', @context.eval('e2e_patient2.vitalSigns()[0].values()[0].units()') + assert_equal Time.gm(2013,11,1), @context.eval('e2e_patient2.vitalSigns()[0].startDate()') + assert_equal 2013, @context.eval('e2e_patient2.vitalSigns()[0].startDate().getUTCFullYear()') + assert_equal 10, @context.eval('e2e_patient2.vitalSigns()[0].startDate().getUTCMonth()') + assert_equal 1, @context.eval('e2e_patient2.vitalSigns()[0].startDate().getUTCDate()') + assert_nil @context.eval('e2e_patient2.vitalSigns()[0].interpretation()') + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index c395124..f4d3a8e 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,11 +1,11 @@ -#require 'cover_me' +require 'cover_me' ENV["RAILS_ENV"] = "test" require File.expand_path('../../config/environment', __FILE__) require 'rails/test_help' require 'factory_girl' -require 'mocha' +require 'mocha/setup' -Factory.find_definitions +FactoryGirl.find_definitions class ActiveSupport::TestCase @@ -19,7 +19,9 @@ def setup pi = HealthDataStandards::Import::C32::PatientImporter.instance patient = pi.parse_c32(doc) patient.save! - patient_json = Mongoid.master['records'].find_one(patient.id).to_json + db = Mongoid.default_session + #patient_json = Mongoid.master['records'].find_one(patient.id).to_json + patient_json = db['records'].find(_id: patient.id).first.to_json patient_api = QueryUtilities.patient_api_javascript.to_s initialize_patient = 'var patient = new hQuery.Patient(barry);' date = Time.new(2010,1,1) @@ -29,12 +31,107 @@ def setup end def dump_database - db = Mongoid.master + #db = Mongoid.master + db = Mongoid.default_session - db.collection('job_logs').remove({}) if db['job_log_events'] - db.collection('results').remove({}) if db['results'] - db.collection('queries').remove({}) if db['queries'] - db.collection('pmn_requests').remove({}) if db['pmn_requests'] + #db.collection('job_logs').remove({}) if db['job_log_events'] + #db.collection('results').remove({}) if db['results'] + #db.collection('queries').remove({}) if db['queries'] + #db.collection('pmn_requests').remove({}) if db['pmn_requests'] + db['job_logs'].drop if db['job_log_events'] + db['results'].drop if db['results'] + db['queries'].drop if db['queries'] + db['pmn_requests'].drop if db['pmn_requests'] +end + +#TODO Work out procedure so scoop-records.json can be recreated automatically when E2E documents or their parsing in hds changes +#Currently, scoop-records.json needs to be built manually. +def load_scoop_database + # Deletes any existing records and loads in scoop records + #`mongoimport -d #{Mongoid.master.name} -h #{Mongoid.master.connection.host_to_try[0]} --drop -c records test/fixtures/scoop-records.json` + + #puts "#{Mongoid.default_session.inspect}" + `mongoimport -d #{Mongoid.default_session.options[:database]} --drop -c records test/fixtures/scoop-records.json` +end + +def dump_jobs + Delayed::Job.destroy_all +end + +def create_query + mf = File.read('test/fixtures/map_reduce/simple_map.js') + rf = File.read('test/fixtures/map_reduce/simple_reduce.js') + Query.create(format: 'js', map: mf, reduce: rf) +end + +def create_job_params + map = Rack::Test::UploadedFile.new(File.join(Rails.root, 'test/fixtures/map_reduce/simple_map.js'), 'application/hqmf+xml') + reduce = Rack::Test::UploadedFile.new(File.join(Rails.root, 'test/fixtures/map_reduce/simple_reduce.js'), 'application/javascript') + functions = Rack::Test::UploadedFile.new(File.join(Rails.root, 'test/fixtures/library_function/simple_function.js'), 'application/javascript') + filter = Rack::Test::UploadedFile.new(File.join(Rails.root, 'test/fixtures/filter/all.json'), 'application/json') + {format: 'js', map: map, reduce: reduce, functions: functions, filter: filter} +end + +def create_hqmf_job_params + hqmf = Rack::Test::UploadedFile.new(File.join(Rails.root, 'test', 'fixtures', 'NQF59New.xml'), 'application/xml') + {format: 'hqmf', hqmf: hqmf} +end + +def create_hqmf_upload + hqmf = Rack::Test::UploadedFile.new(File.join(Rails.root, 'test', 'fixtures', 'NQF59New.xml'), 'application/xml') + # patch Uploaded file - for some reason the tempfile property isn't available like + # it is for a real file upload + class << hqmf + attr_reader :tempfile + end + {query: {hqmf: hqmf}} +end + +class E2EImporterApiTest < ActiveSupport::TestCase + def setup + doc = Nokogiri::XML(File.new('test/fixtures/JOHN_CLEESE_1_25091940.xml')) + doc.root.add_namespace_definition('cda', 'urn:hl7-org:v3') + pi = HealthDataStandards::Import::E2E::PatientImporter.instance + e2e_patient = pi.parse_e2e(doc) + e2e_patient.save! + db = Mongoid.default_session + patient_json = db['records'].find(_id: e2e_patient.id).first.to_json + patient_api = QueryUtilities.patient_api_javascript.to_s + initialize_patient = 'var e2e_patient = new hQuery.Patient(john);' + date = Time.new(2010,1,1) + initialize_date = "var sampleDate = new Date(#{date.to_i*1000});" + #querystr = patient_api + "\nvar john = " + patient_json + ";\n" + initialize_patient + "\n" + initialize_date + #STDERR.puts "querystr: " + querystr + @context = ExecJS.compile(patient_api + "\nvar john = " + patient_json + ";\n" + initialize_patient + "\n" + initialize_date) + end +end + +class E2EImporterApiTest2 < ActiveSupport::TestCase + def setup + doc = Nokogiri::XML(File.new('test/fixtures/MZarilla.xml')) + doc.root.add_namespace_definition('cda', 'urn:hl7-org:v3') + pi = HealthDataStandards::Import::E2E::PatientImporter.instance + e2e_patient2 = pi.parse_e2e(doc) + e2e_patient2.save! + db = Mongoid.default_session + patient_json = db['records'].find(_id: e2e_patient2.id).first.to_json + patient_api = QueryUtilities.patient_api_javascript.to_s + initialize_patient = 'var e2e_patient2 = new hQuery.Patient(melvin);' + date = Time.new(2014,10,2) + initialize_date = "var sampleDate = new Date(#{date.to_i*1000});" + #querystr = patient_api + "\nvar melvin = " + patient_json + ";\n" + initialize_patient + "\n" + initialize_date + #STDERR.puts "querystr: " + querystr + @context = ExecJS.compile(patient_api + "\nvar melvin = " + patient_json + ";\n" + initialize_patient + "\n" + initialize_date) + end +end + +def dump_database + db = Mongoid.default_session + + db['job_logs'].drop if db['job_log_events'] + db['results'].drop if db['results'] + db['queries'].drop if db['queries'] + db['pmn_requests'].drop if db['pmn_requests'] end def dump_jobs diff --git a/test/unit/.gitkeep b/test/unit/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/test/unit/helpers/sysinfo_helper_test.rb b/test/unit/helpers/sysinfo_helper_test.rb new file mode 100644 index 0000000..a165279 --- /dev/null +++ b/test/unit/helpers/sysinfo_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class SysinfoHelperTest < ActionView::TestCase +end diff --git a/test/unit/pdc_job_test.rb b/test/unit/pdc_job_test.rb new file mode 100644 index 0000000..3dfb021 --- /dev/null +++ b/test/unit/pdc_job_test.rb @@ -0,0 +1,227 @@ +require 'test_helper' + +class PdcJobTest < ActiveSupport::TestCase + + setup do + dump_database + dump_jobs + Delayed::Worker.delay_jobs=false + load_scoop_database + end + + test "bmi wc query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/bmi_wc_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 2, results['numerator_has_recorded_values'].to_i + assert_equal 10, results['denominator_patients_>19'].to_i + end + + test "colon screening query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/colon_screening_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 2, results["numerator_has_hemoccult_result"].to_i + assert_equal 5, results["denominator_patients_50-74"].to_i + end + + test "commonly prescribed medications query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/common_medication_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 1, results["A10"].to_i + assert_equal 4, results["B01"].to_i + assert_equal 6, results["C03"].to_i + assert_equal 3, results["C07"].to_i + assert_equal 3, results["C09"].to_i + assert_equal 4, results["C10"].to_i + assert_equal 2, results["H03"].to_i + assert_equal 2, results["M01"].to_i + assert_equal 1, results["N02"].to_i + assert_equal 1, results["N05"].to_i + assert_equal 1, results["N06"].to_i + assert_equal 8, results["R03"].to_i + end + + test "diabetes and bp query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/diabetes_bp_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 10, results['total_pop'].to_i + assert_equal 4, results['denominator_diabetics'].to_i + assert_equal 0, results['numerator_diabetics_bp'].to_i + end + + test "diabetes hgba1c query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/diabetes_hgba1c_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 2, results["numerator_has_hgba1c_result"].to_i + assert_equal 4, results["denominator_diabetics"].to_i + end + + test "diabetes hgba1c value query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/diabetes_hgba1c_value_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 2, results["has_hgba1c_result"].to_i + assert_equal 2, results["numerator_has_matching_hgba1c_value"].to_i + assert_equal 4, results["denominator_diabetics"].to_i + end + + test "diabetes ldl value query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/diabetes_ldl_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 2, results["has_ldl_result"].to_i + assert_equal 1, results["numerator_has_matching_ldl_value"].to_i + assert_equal 4, results["denominator_diabetics"].to_i + end + + test "fasting blood sugar query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/fasting_blood_sugar_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 2, results["numerator_has_blood_sugar_result"].to_i + assert_equal 9, results["denominator_patients_>45"].to_i + end + + test "pneumococcal vaccine query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/pneumococcal_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 3, results["total_pneumovax"].to_i + assert_equal 7, results["denominator_patients_>64"].to_i + assert_equal 1, results["numerator_senior_pop_pneumovax"].to_i + end + + test "polypharmacy query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/polypharmacy_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 10, results["total_population"].to_i + assert_equal 7, results["denominator_sampled_number"].to_i + assert_equal 3, results["numerator_polypharmacy_number"].to_i + end + + test "population profile query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/population_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 1, results["female_40-49"].to_i + assert_equal 1, results["female_50-59"].to_i + assert_equal 1, results["female_60-69"].to_i + assert_equal 1, results["female_70-79"].to_i + assert_equal 2, results["female_80-89"].to_i + assert_equal 1, results["male_60-69"].to_i + assert_equal 2, results["male_70-79"].to_i + assert_equal 1, results["male_90+"].to_i + assert_equal 1, results["total_40-49"].to_i + assert_equal 1, results["total_50-59"].to_i + assert_equal 2, results["total_60-69"].to_i + assert_equal 3, results["total_70-79"].to_i + assert_equal 2, results["total_80-89"].to_i + assert_equal 1, results["total_90+"].to_i + assert_equal 6, results["total_female"].to_i + assert_equal 4, results["total_male"].to_i + assert_equal 10, results["total_population"].to_i + end + + test "primary statins query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/primary_statins_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 4, results["had_statins"].to_i, 4 + assert_equal 4, results["denominator_has_current_statin"].to_i, 4 + assert_equal 2, results["numerator_no_mi_or_stroke"].to_i, 2 + end + + test "renal digoxin value query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/renal_digoxin_value_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 7, results["senior_pop"].to_i + assert_equal 3, results["denominator_senior_pop_impaired_renal"].to_i + assert_equal 2, results["numerator_senior_pop_renal_digoxin"].to_i + end + + test "secondary statins query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/pdc/secondary_statins_map.js') + rf = File.read('test/fixtures/pdc/pdc_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 4, results["had_statins"].to_i + assert_equal 4, results["denominator_has_current_statin"].to_i + assert_equal 2, results["numerator_mi_or_stroke"].to_i + end + +end diff --git a/test/unit/query_executor_test.rb b/test/unit/query_executor_test.rb index e553b6d..a00566d 100644 --- a/test/unit/query_executor_test.rb +++ b/test/unit/query_executor_test.rb @@ -3,7 +3,10 @@ class QueryExecutorTest < ActiveSupport::TestCase def setup - Mongoid.master.drop_collection('query_results') + #Mongoid.master.drop_collection('query_results') + db = Mongoid.default_session + #db.drop_collection('query_results') + db[:query_results].drop if defined?(QueryExecutor.test_setup) QueryExecutor.test_setup end diff --git a/test/unit/query_job_test.rb b/test/unit/query_job_test.rb index dbce282..4bf08b6 100644 --- a/test/unit/query_job_test.rb +++ b/test/unit/query_job_test.rb @@ -12,8 +12,11 @@ class QueryJobTest < ActiveSupport::TestCase Delayed::Worker.delay_jobs=true query = create_query query.job - assert_equal 1, Mongoid.master['queries'].find({}).count - assert_equal :queued, Mongoid.master['queries'].find({}).first['status'] + #assert_equal 1, Mongoid.master['queries'].find({}).count + #assert_equal :queued, Mongoid.master['queries'].find({}).first['status'] + db = Mongoid.default_session + assert_equal 1, db['queries'].find({}).count + assert_equal :queued, db['queries'].find({}).first['status'] end @@ -31,7 +34,8 @@ class QueryJobTest < ActiveSupport::TestCase payload.failure(job) assert_equal Query.find(query.id).status, :failed - Result.collection.save({_id: job.id, value: {}}) + #Result.collection.save({_id: job.id, value: {}}) + Result.collection.insert({_id: job.id, value: {}}) assert_equal Query.find(query.id).status, :failed payload.success(job) diff --git a/test/unit/query_utilities_test.rb b/test/unit/query_utilities_test.rb index 0bfa018..07baed9 100644 --- a/test/unit/query_utilities_test.rb +++ b/test/unit/query_utilities_test.rb @@ -3,7 +3,7 @@ class QueryUtilitesTest < ActiveSupport::TestCase test "Stringification" do - key = BSON::OrderedHash.new + key = Moped::BSON::Document.new key['a'] = 'b' key['c'] = 'd' str = QueryUtilities.stringify_key(key) diff --git a/test/unit/scoop_job_test.rb b/test/unit/scoop_job_test.rb new file mode 100644 index 0000000..a400c39 --- /dev/null +++ b/test/unit/scoop_job_test.rb @@ -0,0 +1,88 @@ +require 'test_helper' + +class ScoopJobTest < ActiveSupport::TestCase + + setup do + dump_database + dump_jobs + Delayed::Worker.delay_jobs=false + load_scoop_database + end + + test "age gender query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/scoop/age_gender_map.js') + rf = File.read('test/fixtures/scoop/scoop_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 4, results["male_>65"].to_i + end + + test "graphical query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/scoop/graphical_builder_demographics_map.js') + rf = File.read('test/fixtures/scoop/graphical_builder_demographics_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_not_nil results + rvalues = results["{\"type\"=>\"population\"}"]['values'] + assert_equal 4, rvalues["filtered_pop_sum"].to_i + assert_equal 6, rvalues["unfound_pop_sum"].to_i + assert_equal 10, rvalues["total_pop_sum"].to_i + end + + test "renal digoxin query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/scoop/renal_digoxin_map.js') + rf = File.read('test/fixtures/scoop/scoop_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 7, results["senior_pop"].to_i + assert_equal 2, results["senior_pop_digoxin_creatinine_abnormal"].to_i + assert_equal 10, results["total_pop"].to_i + end + + test "vital signs overweight query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/scoop/vital_sign_overweight_map.js') + rf = File.read('test/fixtures/scoop/scoop_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 10, results['>19_pop'].to_i + assert_equal 2, results['>19_pop_bmi>30'].to_i + assert_equal 1, results['>19_pop_overweight_wc'].to_i + end + + test "vital signs query works properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/scoop/vital_signs_map.js') + rf = File.read('test/fixtures/scoop/scoop_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 10, results['>19_pop'].to_i + assert_equal 3, results['>19_pop_bp_diastolic'].to_i + assert_equal 3, results['>19_pop_bp_systolic'].to_i + assert_equal 1, results['>19_pop_heartrate'].to_i + assert_equal 2, results['>19_pop_height'].to_i + assert_equal 1, results['>19_pop_temperature'].to_i + assert_equal 1, results['>19_pop_wc'].to_i + assert_equal 2, results['>19_pop_weight'].to_i + assert_equal 10, results['total_pop'].to_i + end + +end diff --git a/test/unit/scoop_regex_test.rb b/test/unit/scoop_regex_test.rb new file mode 100644 index 0000000..17a0414 --- /dev/null +++ b/test/unit/scoop_regex_test.rb @@ -0,0 +1,28 @@ +require 'test_helper' + +class ScoopRegexTest < ActiveSupport::TestCase + + setup do + dump_database + dump_jobs + Delayed::Worker.delay_jobs=false + load_scoop_database + end + + test "regex codes work properly" do + Delayed::Worker.delay_jobs=true + mf = File.read('test/fixtures/scoop/codes_with_regex_map.js') + rf = File.read('test/fixtures/scoop/scoop_general_reduce.js') + query = Query.create(map: mf, reduce: rf) + job = query.job + job.invoke_job + query.reload + results = query.result + assert_equal 10, results['>19_pop'].to_i + assert_equal 2, results['>19_pop_bmi>30'].to_i + assert_equal 1, results['>19_pop_overweight_wc'].to_i + assert_equal 2, results['hasHeight'].to_i + assert_equal 10, results['total_pop'].to_i + end + +end diff --git a/util/README.relay-service b/util/README.relay-service new file mode 100644 index 0000000..6753645 --- /dev/null +++ b/util/README.relay-service @@ -0,0 +1,12 @@ +This server is used to load test files into query-gateway. It can be +started from this directory with the command './relay-service.rb'. +Make sure the query-gateway software is running on localhost:3001 before +running this server. + +The relay service uses port 3000. Modify the ':Port => 3000' setting +in the script if another port will be used. The server can be +accessed with a web browser using "http://localhost:3000". + +IMPORTANT: Set the constant FILE_IMPORT_DIR to the directory where the +E2E xml files are located. The default is to use a './files' +subdirectory of the directory where relay-service.rb is located. diff --git a/util/relay-service.rb b/util/relay-service.rb new file mode 100755 index 0000000..753c11d --- /dev/null +++ b/util/relay-service.rb @@ -0,0 +1,52 @@ +#!/usr/bin/env ruby +# A simple WEBrick web server +# +require 'webrick' +require 'net/http/post/multipart' + +include WEBrick # import WEBrick namespace + +FILE_IMPORT_DIR = './files' + +config={} +config.update(:Port => 3000) +config.update(:DocumentRoot => './') +server = HTTPServer.new(config) + +# Mount servlets +server.mount_proc('/') { |req, resp| + resp.body = 'Delete test patient records
Create test patient records

IMPORTANT: The query-gateway service must be running on localhost:3001 before invoking these services!!!' +} +server.mount_proc('/records/destroy') { |req, resp| + uri = URI.parse('http://localhost:3001/records/destroy') + http = Net::HTTP.new(uri.host, uri.port) + request = Net::HTTP::Delete.new(uri.request_uri) + response = http.request(request) + resp.body = response.body +} +class RecordRelayServlet < HTTPServlet::AbstractServlet + def do_GET(request, response) + Dir.glob("#{FILE_IMPORT_DIR}/*.xml") do |xml_file| + url = URI.parse('http://localhost:3001/records/create') + res = nil + File.open(xml_file) do |xml| + req = Net::HTTP::Post::Multipart.new url.path, 'content' => UploadIO.new(xml, 'text/xml', 'temp_scoop_document.xml') + res = Net::HTTP.start(url.host, url.port) do |http| + http.request(req) + end + end + response.body = res.body + end + raise HTTPStatus::OK + end + alias :do_POST :do_GET # accept POST request +end +server.mount('/records/relay', RecordRelayServlet) + +# Trap signals to shutdown cleanly. +['INT', 'TERM'].each do |signal| + trap(signal) {server.shutdown} +end + +# Start the server +server.start