cqm-models 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. checksums.yaml +7 -0
  2. data/.eslintignore +1 -0
  3. data/.eslintrc.json +26 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +32 -0
  5. data/.gitignore +21 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +42 -0
  8. data/.travis.yml +21 -0
  9. data/Gemfile +5 -0
  10. data/LICENSE.txt +201 -0
  11. data/README.md +26 -0
  12. data/Rakefile +12 -0
  13. data/app/assets/javascripts/AdverseEvent.js +27 -0
  14. data/app/assets/javascripts/AllDataElements.js +120 -0
  15. data/app/assets/javascripts/AllergyIntolerance.js +27 -0
  16. data/app/assets/javascripts/AssessmentPerformed.js +30 -0
  17. data/app/assets/javascripts/AssessmentRecommended.js +27 -0
  18. data/app/assets/javascripts/CareGoal.js +25 -0
  19. data/app/assets/javascripts/CommunicationFromPatientToProvider.js +26 -0
  20. data/app/assets/javascripts/CommunicationFromProviderToPatient.js +26 -0
  21. data/app/assets/javascripts/CommunicationFromProviderToProvider.js +26 -0
  22. data/app/assets/javascripts/Component.js +22 -0
  23. data/app/assets/javascripts/Concept.js +14 -0
  24. data/app/assets/javascripts/DeviceApplied.js +29 -0
  25. data/app/assets/javascripts/DeviceOrder.js +26 -0
  26. data/app/assets/javascripts/DeviceRecommended.js +26 -0
  27. data/app/assets/javascripts/Diagnosis.js +27 -0
  28. data/app/assets/javascripts/DiagnosticStudyOrder.js +27 -0
  29. data/app/assets/javascripts/DiagnosticStudyPerformed.js +33 -0
  30. data/app/assets/javascripts/DiagnosticStudyRecommended.js +27 -0
  31. data/app/assets/javascripts/EncounterOrder.js +27 -0
  32. data/app/assets/javascripts/EncounterPerformed.js +32 -0
  33. data/app/assets/javascripts/EncounterRecommended.js +27 -0
  34. data/app/assets/javascripts/FacilityLocation.js +22 -0
  35. data/app/assets/javascripts/FamilyHistory.js +25 -0
  36. data/app/assets/javascripts/Id.js +22 -0
  37. data/app/assets/javascripts/ImmunizationAdministered.js +30 -0
  38. data/app/assets/javascripts/ImmunizationOrder.js +30 -0
  39. data/app/assets/javascripts/InterventionOrder.js +26 -0
  40. data/app/assets/javascripts/InterventionPerformed.js +29 -0
  41. data/app/assets/javascripts/InterventionRecommended.js +26 -0
  42. data/app/assets/javascripts/LaboratoryTestOrder.js +27 -0
  43. data/app/assets/javascripts/LaboratoryTestPerformed.js +33 -0
  44. data/app/assets/javascripts/LaboratoryTestRecommended.js +27 -0
  45. data/app/assets/javascripts/Measure.js +76 -0
  46. data/app/assets/javascripts/MeasurePackage.js +20 -0
  47. data/app/assets/javascripts/MedicationActive.js +28 -0
  48. data/app/assets/javascripts/MedicationAdministered.js +31 -0
  49. data/app/assets/javascripts/MedicationDischarge.js +30 -0
  50. data/app/assets/javascripts/MedicationDispensed.js +31 -0
  51. data/app/assets/javascripts/MedicationOrder.js +34 -0
  52. data/app/assets/javascripts/Participation.js +21 -0
  53. data/app/assets/javascripts/Patient.js +248 -0
  54. data/app/assets/javascripts/PatientCareExperience.js +23 -0
  55. data/app/assets/javascripts/PatientCharacteristic.js +23 -0
  56. data/app/assets/javascripts/PatientCharacteristicBirthdate.js +24 -0
  57. data/app/assets/javascripts/PatientCharacteristicClinicalTrialParticipant.js +26 -0
  58. data/app/assets/javascripts/PatientCharacteristicEthnicity.js +23 -0
  59. data/app/assets/javascripts/PatientCharacteristicExpired.js +25 -0
  60. data/app/assets/javascripts/PatientCharacteristicPayer.js +24 -0
  61. data/app/assets/javascripts/PatientCharacteristicRace.js +23 -0
  62. data/app/assets/javascripts/PatientCharacteristicSex.js +23 -0
  63. data/app/assets/javascripts/PhysicalExamOrder.js +28 -0
  64. data/app/assets/javascripts/PhysicalExamPerformed.js +31 -0
  65. data/app/assets/javascripts/PhysicalExamRecommended.js +28 -0
  66. data/app/assets/javascripts/ProcedureOrder.js +30 -0
  67. data/app/assets/javascripts/ProcedurePerformed.js +35 -0
  68. data/app/assets/javascripts/ProcedureRecommended.js +30 -0
  69. data/app/assets/javascripts/ProviderCareExperience.js +23 -0
  70. data/app/assets/javascripts/ProviderCharacteristic.js +23 -0
  71. data/app/assets/javascripts/Ratio.js +22 -0
  72. data/app/assets/javascripts/Result.js +28 -0
  73. data/app/assets/javascripts/ResultComponent.js +21 -0
  74. data/app/assets/javascripts/SubstanceAdministered.js +30 -0
  75. data/app/assets/javascripts/SubstanceOrder.js +32 -0
  76. data/app/assets/javascripts/SubstanceRecommended.js +32 -0
  77. data/app/assets/javascripts/Symptom.js +25 -0
  78. data/app/assets/javascripts/ValueSet.js +30 -0
  79. data/app/assets/javascripts/basetypes/Code.js +25 -0
  80. data/app/assets/javascripts/basetypes/DataElement.js +36 -0
  81. data/app/assets/javascripts/basetypes/DateTime.js +18 -0
  82. data/app/assets/javascripts/basetypes/Interval.js +35 -0
  83. data/app/assets/javascripts/basetypes/Quantity.js +20 -0
  84. data/app/assets/javascripts/index.js +12 -0
  85. data/app/models/models.rb +78 -0
  86. data/app/models/qdm/adverse_event.rb +15 -0
  87. data/app/models/qdm/allergy_intolerance.rb +15 -0
  88. data/app/models/qdm/assessment_performed.rb +18 -0
  89. data/app/models/qdm/assessment_recommended.rb +15 -0
  90. data/app/models/qdm/basetypes/code.rb +56 -0
  91. data/app/models/qdm/basetypes/data_element.rb +42 -0
  92. data/app/models/qdm/basetypes/interval.rb +54 -0
  93. data/app/models/qdm/basetypes/quantity.rb +52 -0
  94. data/app/models/qdm/care_goal.rb +13 -0
  95. data/app/models/qdm/communication_from_patient_to_provider.rb +14 -0
  96. data/app/models/qdm/communication_from_provider_to_patient.rb +14 -0
  97. data/app/models/qdm/communication_from_provider_to_provider.rb +14 -0
  98. data/app/models/qdm/component.rb +10 -0
  99. data/app/models/qdm/device_applied.rb +17 -0
  100. data/app/models/qdm/device_order.rb +14 -0
  101. data/app/models/qdm/device_recommended.rb +14 -0
  102. data/app/models/qdm/diagnosis.rb +15 -0
  103. data/app/models/qdm/diagnostic_study_order.rb +15 -0
  104. data/app/models/qdm/diagnostic_study_performed.rb +21 -0
  105. data/app/models/qdm/diagnostic_study_recommended.rb +15 -0
  106. data/app/models/qdm/encounter_order.rb +15 -0
  107. data/app/models/qdm/encounter_performed.rb +20 -0
  108. data/app/models/qdm/encounter_recommended.rb +15 -0
  109. data/app/models/qdm/facility_location.rb +10 -0
  110. data/app/models/qdm/family_history.rb +13 -0
  111. data/app/models/qdm/id.rb +10 -0
  112. data/app/models/qdm/immunization_administered.rb +18 -0
  113. data/app/models/qdm/immunization_order.rb +18 -0
  114. data/app/models/qdm/intervention_order.rb +14 -0
  115. data/app/models/qdm/intervention_performed.rb +17 -0
  116. data/app/models/qdm/intervention_recommended.rb +14 -0
  117. data/app/models/qdm/laboratory_test_order.rb +15 -0
  118. data/app/models/qdm/laboratory_test_performed.rb +21 -0
  119. data/app/models/qdm/laboratory_test_recommended.rb +15 -0
  120. data/app/models/qdm/medication_active.rb +16 -0
  121. data/app/models/qdm/medication_administered.rb +19 -0
  122. data/app/models/qdm/medication_discharge.rb +18 -0
  123. data/app/models/qdm/medication_dispensed.rb +19 -0
  124. data/app/models/qdm/medication_order.rb +22 -0
  125. data/app/models/qdm/participation.rb +9 -0
  126. data/app/models/qdm/patient.rb +201 -0
  127. data/app/models/qdm/patient_care_experience.rb +11 -0
  128. data/app/models/qdm/patient_characteristic.rb +11 -0
  129. data/app/models/qdm/patient_characteristic_birthdate.rb +12 -0
  130. data/app/models/qdm/patient_characteristic_clinical_trial_participant.rb +14 -0
  131. data/app/models/qdm/patient_characteristic_ethnicity.rb +11 -0
  132. data/app/models/qdm/patient_characteristic_expired.rb +13 -0
  133. data/app/models/qdm/patient_characteristic_payer.rb +12 -0
  134. data/app/models/qdm/patient_characteristic_race.rb +11 -0
  135. data/app/models/qdm/patient_characteristic_sex.rb +11 -0
  136. data/app/models/qdm/physical_exam_order.rb +16 -0
  137. data/app/models/qdm/physical_exam_performed.rb +19 -0
  138. data/app/models/qdm/physical_exam_recommended.rb +16 -0
  139. data/app/models/qdm/procedure_order.rb +18 -0
  140. data/app/models/qdm/procedure_performed.rb +23 -0
  141. data/app/models/qdm/procedure_recommended.rb +18 -0
  142. data/app/models/qdm/provider_care_experience.rb +11 -0
  143. data/app/models/qdm/provider_characteristic.rb +11 -0
  144. data/app/models/qdm/ratio.rb +10 -0
  145. data/app/models/qdm/result_component.rb +9 -0
  146. data/app/models/qdm/substance_administered.rb +18 -0
  147. data/app/models/qdm/substance_order.rb +20 -0
  148. data/app/models/qdm/substance_recommended.rb +20 -0
  149. data/app/models/qdm/symptom.rb +13 -0
  150. data/app/models/qdm/tacoma/concept.rb +14 -0
  151. data/app/models/qdm/tacoma/measure.rb +172 -0
  152. data/app/models/qdm/tacoma/measure_package.rb +10 -0
  153. data/app/models/qdm/tacoma/valueset.rb +68 -0
  154. data/bin/console +14 -0
  155. data/bin/setup +8 -0
  156. data/bin/validate_dist.sh +17 -0
  157. data/config/mongoid.yml +6 -0
  158. data/cqm-models.gemspec +29 -0
  159. data/data/oids.json +584 -0
  160. data/dist/index.js +157647 -0
  161. data/lib/cqm/models.rb +1 -0
  162. data/lib/generate_models.rb +330 -0
  163. data/modelinfo/qdm-modelinfo-4.2.xml +515 -0
  164. data/modelinfo/qdm-modelinfo-4.3.xml +521 -0
  165. data/modelinfo/qdm-modelinfo-5.0.1.xml +436 -0
  166. data/modelinfo/qdm-modelinfo-5.0.2.xml +445 -0
  167. data/modelinfo/qdm-modelinfo-5.0.xml +429 -0
  168. data/modelinfo/qdm-modelinfo-5.3.xml +524 -0
  169. data/package.json +34 -0
  170. data/templates/all_data_elements_template.js.erb +4 -0
  171. data/templates/index_template.js.erb +12 -0
  172. data/templates/models_template.rb.erb +21 -0
  173. data/templates/mongoose_template.js.erb +20 -0
  174. data/templates/patient_extension.rb.erb +194 -0
  175. data/templates/patient_template.js.erb +247 -0
  176. data/tmp/.keep +0 -0
  177. data/yarn.lock +1901 -0
  178. metadata +320 -0
@@ -0,0 +1,13 @@
1
+ module QDM
2
+ # app/models/qdm/patient_characteristic_expired.rb
3
+ class PatientCharacteristicExpired < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :expiredDatetime, type: DateTime
7
+ field :cause, type: QDM::Code
8
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.57'
9
+ field :category, type: String, default: 'patient_characteristic'
10
+ field :qdmStatus, type: String, default: 'expired'
11
+ field :qdmVersion, type: String, default: '5.3'
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module QDM
2
+ # app/models/qdm/patient_characteristic_payer.rb
3
+ class PatientCharacteristicPayer < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :relevantPeriod, type: QDM::Interval
7
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.58'
8
+ field :category, type: String, default: 'patient_characteristic'
9
+ field :qdmStatus, type: String, default: 'payer'
10
+ field :qdmVersion, type: String, default: '5.3'
11
+ end
12
+ end
@@ -0,0 +1,11 @@
1
+ module QDM
2
+ # app/models/qdm/patient_characteristic_race.rb
3
+ class PatientCharacteristicRace < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.59'
7
+ field :category, type: String, default: 'patient_characteristic'
8
+ field :qdmStatus, type: String, default: 'race'
9
+ field :qdmVersion, type: String, default: '5.3'
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module QDM
2
+ # app/models/qdm/patient_characteristic_sex.rb
3
+ class PatientCharacteristicSex < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.55'
7
+ field :category, type: String, default: 'patient_characteristic'
8
+ field :qdmStatus, type: String, default: 'gender'
9
+ field :qdmVersion, type: String, default: '5.3'
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module QDM
2
+ # app/models/qdm/physical_exam_order.rb
3
+ class PhysicalExamOrder < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :reason, type: QDM::Code
8
+ field :method, type: QDM::Code
9
+ field :anatomicalLocationSite, type: QDM::Code
10
+ field :negationRationale, type: QDM::Code
11
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.61'
12
+ field :category, type: String, default: 'physical_exam'
13
+ field :qdmStatus, type: String, default: 'order'
14
+ field :qdmVersion, type: String, default: '5.3'
15
+ end
16
+ end
@@ -0,0 +1,19 @@
1
+ module QDM
2
+ # app/models/qdm/physical_exam_performed.rb
3
+ class PhysicalExamPerformed < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :relevantPeriod, type: QDM::Interval
8
+ field :reason, type: QDM::Code
9
+ field :method, type: QDM::Code
10
+ field :result
11
+ field :anatomicalLocationSite, type: QDM::Code
12
+ field :negationRationale, type: QDM::Code
13
+ field :components, type: Array
14
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.62'
15
+ field :category, type: String, default: 'physical_exam'
16
+ field :qdmStatus, type: String, default: 'performed'
17
+ field :qdmVersion, type: String, default: '5.3'
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ module QDM
2
+ # app/models/qdm/physical_exam_recommended.rb
3
+ class PhysicalExamRecommended < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :reason, type: QDM::Code
8
+ field :method, type: QDM::Code
9
+ field :anatomicalLocationSite, type: QDM::Code
10
+ field :negationRationale, type: QDM::Code
11
+ field :hqmfOid, type: String, default: '22.16.840.1.113883.10.20.28.3.63'
12
+ field :category, type: String, default: 'physical_exam'
13
+ field :qdmStatus, type: String, default: 'recommended'
14
+ field :qdmVersion, type: String, default: '5.3'
15
+ end
16
+ end
@@ -0,0 +1,18 @@
1
+ module QDM
2
+ # app/models/qdm/procedure_order.rb
3
+ class ProcedureOrder < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :reason, type: QDM::Code
8
+ field :method, type: QDM::Code
9
+ field :anatomicalApproachSite, type: QDM::Code
10
+ field :anatomicalLocationSite, type: QDM::Code
11
+ field :ordinality, type: QDM::Code
12
+ field :negationRationale, type: QDM::Code
13
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.66'
14
+ field :category, type: String, default: 'procedure'
15
+ field :qdmStatus, type: String, default: 'order'
16
+ field :qdmVersion, type: String, default: '5.3'
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ module QDM
2
+ # app/models/qdm/procedure_performed.rb
3
+ class ProcedurePerformed < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :relevantPeriod, type: QDM::Interval
8
+ field :reason, type: QDM::Code
9
+ field :method, type: QDM::Code
10
+ field :result
11
+ field :status, type: QDM::Code
12
+ field :anatomicalApproachSite, type: QDM::Code
13
+ field :anatomicalLocationSite, type: QDM::Code
14
+ field :ordinality, type: QDM::Code
15
+ field :incisionDatetime, type: DateTime
16
+ field :negationRationale, type: QDM::Code
17
+ field :components, type: Array
18
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.67'
19
+ field :category, type: String, default: 'procedure'
20
+ field :qdmStatus, type: String, default: 'performed'
21
+ field :qdmVersion, type: String, default: '5.3'
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ module QDM
2
+ # app/models/qdm/procedure_recommended.rb
3
+ class ProcedureRecommended < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :reason, type: QDM::Code
8
+ field :method, type: QDM::Code
9
+ field :anatomicalApproachSite, type: QDM::Code
10
+ field :anatomicalLocationSite, type: QDM::Code
11
+ field :ordinality, type: QDM::Code
12
+ field :negationRationale, type: QDM::Code
13
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.68'
14
+ field :category, type: String, default: 'procedure'
15
+ field :qdmStatus, type: String, default: 'recommended'
16
+ field :qdmVersion, type: String, default: '5.3'
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module QDM
2
+ # app/models/qdm/provider_care_experience.rb
3
+ class ProviderCareExperience < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.70'
8
+ field :category, type: String, default: 'care_experience'
9
+ field :qdmVersion, type: String, default: '5.3'
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module QDM
2
+ # app/models/qdm/provider_characteristic.rb
3
+ class ProviderCharacteristic < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.71'
8
+ field :category, type: String, default: 'provider_characteristic'
9
+ field :qdmVersion, type: String, default: '5.3'
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ module QDM
2
+ # app/models/qdm/ratio.rb
3
+ class Ratio < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :numerator, type: QDM::Quantity
7
+ field :denominator, type: QDM::Quantity
8
+ field :qdmVersion, type: String, default: '5.3'
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module QDM
2
+ # app/models/qdm/result_component.rb
3
+ class ResultComponent < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :referenceRange, type: QDM::Interval
7
+ field :qdmVersion, type: String, default: '5.3'
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module QDM
2
+ # app/models/qdm/substance_administered.rb
3
+ class SubstanceAdministered < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :relevantPeriod, type: QDM::Interval
8
+ field :dosage, type: QDM::Quantity
9
+ field :supply, type: QDM::Quantity
10
+ field :frequency, type: QDM::Code
11
+ field :route, type: QDM::Code
12
+ field :negationRationale, type: QDM::Code
13
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.73'
14
+ field :category, type: String, default: 'substance'
15
+ field :qdmStatus, type: String, default: 'administered'
16
+ field :qdmVersion, type: String, default: '5.3'
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module QDM
2
+ # app/models/qdm/substance_order.rb
3
+ class SubstanceOrder < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :reason, type: QDM::Code
8
+ field :dosage, type: QDM::Quantity
9
+ field :supply, type: QDM::Quantity
10
+ field :frequency, type: QDM::Code
11
+ field :method, type: QDM::Code
12
+ field :refills, type: Integer
13
+ field :route, type: QDM::Code
14
+ field :negationRationale, type: QDM::Code
15
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.77'
16
+ field :category, type: String, default: 'substance'
17
+ field :qdmStatus, type: String, default: 'order'
18
+ field :qdmVersion, type: String, default: '5.3'
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module QDM
2
+ # app/models/qdm/substance_recommended.rb
3
+ class SubstanceRecommended < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :authorDatetime, type: DateTime
7
+ field :reason, type: QDM::Code
8
+ field :dosage, type: QDM::Quantity
9
+ field :supply, type: QDM::Quantity
10
+ field :frequency, type: QDM::Code
11
+ field :method, type: QDM::Code
12
+ field :refills, type: Integer
13
+ field :route, type: QDM::Code
14
+ field :negationRationale, type: QDM::Code
15
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.78'
16
+ field :category, type: String, default: 'substance'
17
+ field :qdmStatus, type: String, default: 'recommended'
18
+ field :qdmVersion, type: String, default: '5.3'
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module QDM
2
+ # app/models/qdm/symptom.rb
3
+ class Symptom < DataElement
4
+ include Mongoid::Document
5
+ embedded_in :patient
6
+ field :prevalencePeriod, type: QDM::Interval
7
+ field :severity, type: QDM::Code
8
+ field :hqmfOid, type: String, default: '2.16.840.1.113883.10.20.28.3.116'
9
+ field :qrdaOid, type: String, default: '2.16.840.1.113883.10.20.24.3.136'
10
+ field :category, type: String, default: 'symptom'
11
+ field :qdmVersion, type: String, default: '5.3'
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module QDM
2
+ # Concept is an individual code within a ValueSet, including all of the associated metadata
3
+ # such as code system, version, and display name
4
+ class Concept
5
+ include Mongoid::Document
6
+ field :code, type: String
7
+ field :code_system_name, type: String
8
+ field :code_system_version, type: String
9
+ field :display_name, type: String
10
+ field :code_system, type: String
11
+ scope :by_code_system_name, ->(cs) { where(code_system_name: cs) }
12
+ scope :by_code_system, ->(cs) { where(code_system: cs) }
13
+ end
14
+ end
@@ -0,0 +1,172 @@
1
+ module QDM
2
+ # Measure contains the information necessary to represent the CQL version of a Clinical Quality Measure,
3
+ # As needed by the Bonnie & Cypress applications
4
+ class Measure
5
+ include Mongoid::Document
6
+ include Mongoid::Timestamps
7
+
8
+ DEFAULT_EFFECTIVE_DATE = Time.gm(2012, 12, 31, 23, 59).to_i
9
+ MP_START_DATE = Time.gm(2012, 1, 1, 0, 0).to_i
10
+ TYPES = %w[ep eh].freeze
11
+
12
+ IPP = 'IPP'.freeze
13
+ DENOM = 'DENOM'.freeze
14
+ NUMER = 'NUMER'.freeze
15
+ NUMEX = 'NUMEX'.freeze
16
+ DENEXCEP = 'DENEXCEP'.freeze
17
+ DENEX = 'DENEX'.freeze
18
+ MSRPOPL = 'MSRPOPL'.freeze
19
+ OBSERV = 'OBSERV'.freeze
20
+ MSRPOPLEX = 'MSRPOPLEX'.freeze
21
+
22
+ STRAT = 'STRAT'.freeze
23
+
24
+ ALL_POPULATION_CODES = [STRAT, IPP, DENOM, DENEX, NUMER, NUMEX, DENEXCEP, MSRPOPL, OBSERV, MSRPOPLEX].freeze
25
+
26
+ CQL_SKIP_STATEMENTS = ['SDE Ethnicity', 'SDE Payer', 'SDE Race', 'SDE Sex'].freeze
27
+
28
+ # ID/other measure information
29
+ field :id, type: String
30
+ field :measure_id, type: String
31
+ field :hqmf_id, type: String
32
+ field :hqmf_set_id, type: String
33
+ field :hqmf_version_number, type: Integer
34
+ field :cms_id, type: String
35
+ field :title, type: String, default: ''
36
+ field :description, type: String, default: ''
37
+ field :type, type: String
38
+ field :category, type: String, default: 'uncategorized'
39
+
40
+ # Measure type variables
41
+ field :episode_of_care, type: Boolean
42
+ field :continuous_variable, type: Boolean
43
+ field :episode_ids, type: Array
44
+
45
+ # Publishing data (used by Bonnie)
46
+ field :published, type: Boolean
47
+ field :publish_date, type: Date
48
+ field :version, type: Integer
49
+
50
+ # ELM/CQL Measure-logic related data
51
+ field :elm_annotations, type: Hash
52
+ field :cql, type: Array
53
+ field :elm, type: Array
54
+ field :main_cql_library, type: String
55
+ field :cql_statement_dependencies, type: Hash
56
+
57
+ # HQMF/Tacoma-specific Measure-logic related data
58
+ field :population_criteria, type: Hash
59
+ field :data_criteria, type: Hash
60
+ field :source_data_criteria, type: Hash
61
+ field :measure_period, type: Hash
62
+ field :measure_attributes, type: Array
63
+ field :populations, type: Array
64
+ field :populations_cql_map, type: Hash
65
+ field :observations, type: Array
66
+
67
+ field :value_set_oids, type: Array, default: []
68
+ field :value_set_oid_version_objects, type: Array, default: []
69
+
70
+ field :complexity, type: Hash
71
+
72
+ # Relations to other model classes
73
+ belongs_to :user
74
+ belongs_to :bundle, class_name: 'HealthDataStandards::CQM::Bundle'
75
+ has_and_belongs_to_many :records, inverse_of: nil
76
+ has_one :package, class_name: 'CqlMeasurePackage', inverse_of: :measure, dependent: :destroy
77
+
78
+ scope :by_measure_id, ->(id) { where('measure_id' => id) }
79
+ scope :by_type, ->(type) { where('type' => type) }
80
+ scope :by_user, ->(user) { where user_id: user.id }
81
+
82
+ index 'user_id' => 1
83
+ # Find the measures matching a patient
84
+ def self.for_patient(record)
85
+ where user_id: record.user_id, hqmf_set_id: { '$in' => record.measure_ids }
86
+ end
87
+
88
+ def value_sets
89
+ options = { oid: value_set_oids }
90
+ options[:user_id] = user.id if user?
91
+ @value_sets ||= HealthDataStandards::SVS::ValueSet.in(options)
92
+ @value_sets
93
+ end
94
+
95
+ # Returns the hqmf-parser's ruby implementation of an HQMF document.
96
+ # Rebuild from population_criteria, data_criteria, and measure_period JSON
97
+ def as_hqmf_model
98
+ json = {
99
+ 'id' => measure_id,
100
+ 'title' => title,
101
+ 'description' => description,
102
+ 'population_criteria' => population_criteria,
103
+ 'data_criteria' => data_criteria,
104
+ 'source_data_criteria' => source_data_criteria,
105
+ 'measure_period' => measure_period,
106
+ 'attributes' => measure_attributes,
107
+ 'populations' => populations,
108
+ 'hqmf_id' => hqmf_id,
109
+ 'hqmf_set_id' => hqmf_set_id,
110
+ 'hqmf_version_number' => hqmf_version_number,
111
+ 'cms_id' => cms_id
112
+ }
113
+ HQMF::Document.from_json(json)
114
+ end
115
+
116
+ def all_data_criteria
117
+ as_hqmf_model.all_data_criteria
118
+ end
119
+
120
+ # Note whether or not the measure is a continuous variable measure.
121
+ before_save :set_continuous_variable
122
+ def set_continuous_variable
123
+ # The return value of this function is not related to whether or not this
124
+ # measure is a CV measure. The true return value ensures false is not
125
+ # accidentally returned here, which would cause the chain of 'before_*' to
126
+ # stop executing.
127
+ self.continuous_variable = populations.map(&:keys).flatten.uniq.include? HQMF::PopulationCriteria::MSRPOPL
128
+ true
129
+ end
130
+
131
+ # When saving calculate the cyclomatic complexity of the measure
132
+ # TODO: Do we want to consider a measure other than "cyclomatic complexity" for CQL?
133
+ # TODO: THIS IS NOT CYCLOMATIC COMPLEXITY, ALL MULTIPLE ELEMENT EXPRESSIONS GET COUNTED AS HIGHER COMPLEXITY, NOT JUST LOGICAL
134
+ before_save :calculate_complexity
135
+ def calculate_complexity
136
+ # We calculate the complexity for each statement, and (at least for now) store the result in the same way
137
+ # we store the complexity for QDM variables
138
+ # TODO: consider whether this is too much of a force fit
139
+ self.complexity = { variables: [] }
140
+ # Recursively look through an expression to count the logical branches
141
+ def count_expression_logical_branches(expression)
142
+ case expression
143
+ when nil
144
+ 0
145
+ when Array
146
+ expression.map { |exp| count_expression_logical_branches(exp) }.sum
147
+ when Hash
148
+ case expression['type']
149
+ when 'And', 'Or', 'Not'
150
+ count_expression_logical_branches(expression['operand'])
151
+ when 'Query'
152
+ # TODO: Do we need to look into the source side of the query? Can there be logical operators there?
153
+ count_expression_logical_branches(expression['where']) + count_expression_logical_branches(expression['relationship'])
154
+ else
155
+ 1
156
+ end
157
+ else
158
+ 0
159
+ end
160
+ end
161
+
162
+ # Determine the complexity of each statement
163
+ elm.each do |elm|
164
+ next unless (statements = elm.try(:[], 'library').try(:[], 'statements').try(:[], 'def'))
165
+ statements.each do |statement|
166
+ complexity[:variables] << { name: statement['name'], complexity: count_expression_logical_branches(statement['expression']) }
167
+ end
168
+ end
169
+ complexity
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,10 @@
1
+ module QDM
2
+ # MeasurePackage stores the uploaded file for a given Measure, so it can be recreated if need be
3
+ class MeasurePackage
4
+ include Mongoid::Document
5
+ include Mongoid::Timestamps
6
+
7
+ field :file, type: BSON::Binary
8
+ belongs_to :measure, class_name: 'Measure', inverse_of: :package
9
+ end
10
+ end
@@ -0,0 +1,68 @@
1
+ module QDM
2
+ # ValueSet represents a collection of Concepts, used by the Measures to specify a set of codes for a particular topic
3
+ class ValueSet
4
+ include Mongoid::Document
5
+ field :oid, type: String
6
+ field :display_name, type: String
7
+ field :version, type: String
8
+ field :user_id, type: String # Eventually we need to delete this from bundles when exporting
9
+ field :categories, type: Hash
10
+
11
+ index(oid: 1)
12
+ embeds_many :concepts
13
+ index 'concepts.code' => 1
14
+ index 'concepts.code_system' => 1
15
+ index 'concepts.code_system_name' => 1
16
+ index 'bundle_id' => 1
17
+ scope :by_oid, ->(oid) { where(oid: oid) }
18
+
19
+ # Provides an Array of Hashes. Each code system gets its own Hash
20
+ # The hash has a key of "set" for the code system name and "values"
21
+ # for the actual code list
22
+ def code_set_map
23
+ codes = []
24
+ concept_pairs = concepts.each_with_object({}) do |concept, memo|
25
+ memo[concept.code_system_name] ||= []
26
+ memo[concept.code_system_name] << concept.code
27
+ end
28
+ concept_pairs.each_pair do |code_set, code_list|
29
+ codes << { 'set' => code_set, 'values' => code_list }
30
+ end
31
+
32
+ codes
33
+ end
34
+
35
+ def self.load_from_xml(doc)
36
+ doc.root.add_namespace_definition('vs', 'urn:ihe:iti:svs:2008')
37
+ vs_element = doc.at_xpath('/vs:RetrieveValueSetResponse/vs:ValueSet|/vs:RetrieveMultipleValueSetsResponse/vs:DescribedValueSet')
38
+ return unless vs_element
39
+ vs = ValueSet.new(oid: vs_element['ID'], display_name: vs_element['displayName'], version: vs_element['version'])
40
+ vs.concepts = extract_concepts(vs_element)
41
+ vs.categories = extract_categories(vs_element)
42
+ vs
43
+ end
44
+
45
+ def self.extract_concepts(vs_element)
46
+ vs_element.xpath('//vs:Concept').collect do |con|
47
+ code_system_name = HealthDataStandards::Util::CodeSystemHelper::CODE_SYSTEMS[con['codeSystem']] || con['codeSystemName']
48
+ Concept.new(code: con['code'],
49
+ code_system_name: code_system_name,
50
+ code_system_version: con['codeSystemVersion'],
51
+ display_name: con['displayName'], code_system: con['codeSystem'])
52
+ end
53
+ end
54
+
55
+ def self.extract_categories(vs_element)
56
+ category_hash = Hash.new { |h, k| h[k] = [] }
57
+ groups_with_categories = vs_element.xpath("//vs:Group/@ID[../@displayName='CATEGORY']")
58
+ groups_with_categories.each do |group_number|
59
+ measure = vs_element.xpath("//vs:Group[@displayName='CMS eMeasure ID' and @ID='#{group_number}']/vs:Keyword").text
60
+ categories_for_group = vs_element.xpath("//vs:Group[@displayName='CATEGORY' and @ID='#{group_number}']/vs:Keyword")
61
+ categories_for_group.each do |category|
62
+ category_hash[measure] << category.text
63
+ end
64
+ end
65
+ !category_hash.empty? ? category_hash : nil
66
+ end
67
+ end
68
+ end
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "cqm/models"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+
3
+ mkdir -p tmp/dist/
4
+
5
+ # dist_test browserifies index.js to tmp/dist
6
+ yarn run dist_test
7
+
8
+ # comm -3 only returns lines that differ between the two files. If none are different, diff will be empty
9
+ diff=`diff dist/index.js tmp/dist/index.js`
10
+
11
+ # Exit with a non-zero code if the diff isn't empty
12
+ if [ "$diff" != "" ]; then
13
+ echo "dist/index.js is out of date. Please run 'yarn run dist' locally and commit/push the result"
14
+ exit 1
15
+ fi
16
+
17
+ echo "dist/index.js is up to date"
@@ -0,0 +1,6 @@
1
+ test:
2
+ clients:
3
+ default:
4
+ database: cqm_models_test
5
+ hosts:
6
+ - localhost:27017
@@ -0,0 +1,29 @@
1
+ lib = File.expand_path('lib', __dir__)
2
+
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'cqm-models'
7
+ spec.version = '0.7.2'
8
+ spec.authors = ['aholmes@mitre.org', 'mokeefe@mitre.org', 'lades@mitre.org']
9
+
10
+ spec.summary = 'Mongo models that correspond to the QDM specification.'
11
+ spec.description = 'This library contains auto generated Mongoid (Ruby) and Mongoose (JavaScript) models that correspond to the QDM (Quality Data Model) specification.'
12
+ spec.homepage = 'https://github.com/projecttacoma/cqm-models'
13
+ spec.license = 'Apache-2.0'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
+ f.match(%r{^(test|spec|features)/})
17
+ end
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.15'
23
+ spec.add_development_dependency 'byebug', '~> 10.0.0'
24
+ spec.add_development_dependency 'mongoid', '~> 6.3.0'
25
+ spec.add_development_dependency 'rails', '~> 5.1'
26
+ spec.add_development_dependency 'rake', '~> 10.0'
27
+ spec.add_development_dependency 'rspec', '~> 3.0'
28
+ spec.add_development_dependency 'rubocop', '~> 0.54.0'
29
+ end