conceptql 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (1192) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +32 -104
  4. data/Gemfile +2 -0
  5. data/README.md +43 -21
  6. data/Rakefile +34 -0
  7. data/conceptql.gemspec +3 -4
  8. data/config/provenance.yml +454 -0
  9. data/doc/converter.rb +33 -0
  10. data/doc/metadata.md +89 -0
  11. data/doc/spec.md +1775 -861
  12. data/doc/spec.md.cql +1930 -0
  13. data/doc/spec/02f44ad35d266ddd0a4df1691d26bf4a297b30604fc3f44b0391d6d852d23a9f.png +0 -0
  14. data/doc/spec/0360fc0c2b7a88fd82ffc4d13387b76766649d5d42aa8f9349bbf60a81ac6119.png +0 -0
  15. data/doc/spec/04491942fcbd741982514f9eb12aeecf3d54b5b69a2b50c8331f7700169d5521.png +0 -0
  16. data/doc/spec/05f9b844571ffceeed2def3025fb60c68552817b8b73d3c8a76939dbc08b7c65.png +0 -0
  17. data/doc/spec/067241a3579767a802d4f8e20fd35b60adbe377c9a6512ef135f164a5accfb27.png +0 -0
  18. data/doc/spec/1102fa717b1c2df67af5220bf3ae219afafd79be7bba0c117e301983385ada52.png +0 -0
  19. data/doc/spec/11f57941951bad5a75f9a16f38a31a3c6bf3046a475aac6e398e780892fab4ad.png +0 -0
  20. data/doc/spec/15268bc45993d3f57ccf915877f91e48bdee684f24faa614249915833cac4af9.png +0 -0
  21. data/doc/spec/253845fe6162621af407ebd110296ff4f6d8a3f23ec75dfb4ea8cda30be71262.png +0 -0
  22. data/doc/spec/26fd52b5ac55438dd9f81b4a3f3913f1058c9f225c8a5e129007c1e9413d5881.png +0 -0
  23. data/doc/spec/2b57886a9cba66bb696e4b399c51ad0dc95cd64b952709fafc819a79d573f09e.png +0 -0
  24. data/doc/spec/307a8b5a7edd6e42f8be16523a4c939faf1a0533385c861d7004b6af8addd7d1.png +0 -0
  25. data/doc/spec/328467a6a419c7c05e299b8097e5e000686068ded8dc6d5f2e2de6f51976c315.png +0 -0
  26. data/doc/spec/39d6a8eb71cae51b1d6937c97134e51f04fd47c54535ff0915fe6a8b4f197fb2.png +0 -0
  27. data/doc/spec/3f46dee4d775d1a29d52b68af6552f8ea3abd8303094e749714fc77bd7958155.png +0 -0
  28. data/doc/spec/44ec6743d5d77d15b8a487c2058bf3e455d34adc91c46ea05767f6e0e471a75e.png +0 -0
  29. data/doc/spec/462153be527b28dc2cb5259c0aec62e1f529e8b60dc6e9c23fd1e06e8be933c9.png +0 -0
  30. data/doc/spec/4a3b47ed1c54f96ebdae693d41c36c51884c4546ef799a4108085708fb7b964e.png +0 -0
  31. data/doc/spec/514f263e976d07c0d9e0a86c79bcbdcddc7d444d7b72135294ad78758effd28f.png +0 -0
  32. data/doc/spec/58113a57a37431a402d2547369eba3a481bf1dbbfd82dc384406a5c91f6df01f.png +0 -0
  33. data/doc/spec/5d331d74c460d75814b2d3138a9b7d90b5ddb2dcd85e1f5f260d183745fc3a1e.png +0 -0
  34. data/doc/spec/5d6ff62038b75d6f240d65f35d1520a131c221f47d3801554c8c2be5d528ebb0.png +0 -0
  35. data/doc/spec/62323426e381ec21c967971a67e1f4a6d89dae92154bd937284e00b67f67fdd3.png +0 -0
  36. data/doc/spec/6705af65d728c0d5c50d6c4d46253017a91eb459dbb1f40f92449f05d5562f4a.png +0 -0
  37. data/doc/spec/68fac940a32c7e40caacf8e560c61da552d57633d015ba98f2e98ec040a00c5b.png +0 -0
  38. data/doc/spec/6a34c0ef589c9c976fe41f3e67e799e198499f5b9c3ebfd240fb91f73e893573.png +0 -0
  39. data/doc/spec/6b48534236697d1ccfa1f5403764782f9d228f9eb706789cfa80203882b7b13a.png +0 -0
  40. data/doc/spec/7aa76b4d29874719466c2cbafc9936e9f12e504bf31e1a09d26ca3fffa8ba1a6.png +0 -0
  41. data/doc/spec/7b9db2986ab9ada45cfb9451ef87ff1a2d99c908083334b7ccdceb8a92387fa9.png +0 -0
  42. data/doc/spec/8101d9b89d9ba8070d585432707b43a8acdb4c2a3e9d37c3f7114b5e3ea9e800.png +0 -0
  43. data/doc/spec/886bf85249a704668a55c5161bceaac10be4a41a94b91606f49851dfa017526c.png +0 -0
  44. data/doc/spec/8ed478d8c81a58a202d0c51348fca246df206fc24a0567b163d4e0bdab56ca46.png +0 -0
  45. data/doc/spec/9139440329dcb815df89bc70182c3827868402a74ff64d0253706dcaff723dca.png +0 -0
  46. data/doc/spec/99392f56dfb0e5be3f45a12a7f1ba846d094e430f526dfeaa30b606837cd34c0.png +0 -0
  47. data/doc/spec/a4450e8c0fe0e2fde92fe9bd61952f907b1976c1aa3ba963b809bed079d42b09.png +0 -0
  48. data/doc/spec/a4bc7382a1154ea9856544fd48418f3dd9ce474ca94b8859fc323749c6cc1f55.png +0 -0
  49. data/doc/spec/a79274742cf6fac6f6c9f4a0eb651aeb452f9c43b537c8e6ccaefecd05b7105c.png +0 -0
  50. data/doc/spec/a9b4528726adec2a90f3f00139d8d0492f13c51f03c2f9ed6a5134b1b26b44a9.png +0 -0
  51. data/doc/spec/af5ae3787e80bf0771f18f1a04fe4c5d9291e1e0f963ac408a7bc198d2f1ee28.png +0 -0
  52. data/doc/spec/ba572c4f4dbade65be55f141df16cf7b3e7d09e0aec4e4e5debc4f2075277371.png +0 -0
  53. data/doc/spec/ba90ef705f7be91c53c5eb4a81a439fa0f7c48532214bd3db3cc5c069160543e.png +0 -0
  54. data/doc/spec/c1d0402862221d85aceedc7d76b3f82149b612cbd972f14d0ca9011e1e2c455c.png +0 -0
  55. data/doc/spec/c2157d8a6b73abe4f22ba5042159f32502c74bf6d762be28d2df6831586822c7.png +0 -0
  56. data/doc/spec/c5329a7f4937096a57b2e01efb9d542f84a4e2329a1e9381d08c630583ccad37.png +0 -0
  57. data/doc/spec/c82077b9455d0f9abc2c45ee1a298e38b99c9ce9cd685f65d87b376d7718d7ad.png +0 -0
  58. data/doc/spec/c93dd18894a245a5647f99e1867d3779e4cd34c9c8f8860600ff0c837a5ffa53.png +0 -0
  59. data/doc/spec/cc960a268d51ccf2ebde657d36848f780213834844900018bce3d111843f7b0f.png +0 -0
  60. data/doc/spec/d39452b58257c95a7cba07afed4877417b0c227f3690e2bff22c9eca89eac845.png +0 -0
  61. data/doc/spec/d64993258ffbef9406d9ab9136de7af530626b3a69e9eeb75835e11f11dabf62.png +0 -0
  62. data/doc/spec/da450cdd0c94a1301bd98560339a45caa8041e09974352a56ecfb144e9a5e4d4.png +0 -0
  63. data/doc/spec/dbc66b3ae6bd7123d77dd04b64f8a24498d048725a55c5340b15f5ae0a1ff307.png +0 -0
  64. data/doc/spec/de589af36fa854e006a1563c93e644e2210f2a5616babb779f7f38aadb6c1ed7.png +0 -0
  65. data/doc/spec/defbd0b853d895802663f507761ad297d82e167f516c6082686a2a19b76012c5.png +0 -0
  66. data/doc/spec/e1cb0863b21e14256d61a54200316791f6547c78ba2f0156c110f4500f9bbd49.png +0 -0
  67. data/doc/spec/e8630103287f7c9d28eff40b3b1826e24846e776b877f7b8554257acbe621e1c.png +0 -0
  68. data/doc/spec/e9b384fa7dec5f1a06479c4b289e06b1e60e4f23f7630aff6d03c52595f500f8.png +0 -0
  69. data/doc/spec/ea935ac31f3b57ff373646780a1fba34a38c9e086dc771eb7fc16c65a7e20cfc.png +0 -0
  70. data/doc/spec/eb8f5511f7d88bd0f8ba73420fc10f7c78405db7f4373d778a827058707f888e.png +0 -0
  71. data/doc/spec/ebacbd092e3d1a3c7b745a381e51e8ff9d63a21db23a16940193e18e57bc866f.png +0 -0
  72. data/doc/spec/ed039f82867241393b1a6a7153d3690461103934c72c1f3eaa3d99a12bb40885.png +0 -0
  73. data/doc/spec/ee283d6a4b69cf10da2df703be3a16830be9cd8cd4f68c5f7afdf558ea28fa76.png +0 -0
  74. data/doc/spec/f0c734b099841a754ae0366afb00e992ad4814479b65e4a7de23c6e3dd85c09a.png +0 -0
  75. data/doc/spec/f6b4fc31703cfb6327bbbd4614af8bb72da6d39fa3d53ada63a70157f2fad80e.png +0 -0
  76. data/doc/spec/f766f2e3aa13420e3ba0f823ac7956b311ed7c6c20be26b72324fadd87f36712.png +0 -0
  77. data/doc/spec/ff7d5b5573d09bd7c4cdd3aeda124d18bf82ec46673a62881b399a75d69f3f53.png +0 -0
  78. data/lib/conceptql.rb +21 -1
  79. data/lib/conceptql/annotate_grapher.rb +127 -0
  80. data/lib/conceptql/behaviors/drugish.rb +12 -0
  81. data/lib/conceptql/behaviors/labish.rb +13 -0
  82. data/lib/conceptql/behaviors/metadatable.rb +156 -71
  83. data/lib/conceptql/behaviors/provenanceable.rb +30 -0
  84. data/lib/conceptql/cli.rb +81 -37
  85. data/lib/conceptql/database.rb +42 -0
  86. data/lib/conceptql/date_adjuster.rb +22 -4
  87. data/lib/conceptql/fake_annotater.rb +129 -0
  88. data/lib/conceptql/knitter.rb +221 -0
  89. data/lib/conceptql/nodifier.rb +34 -23
  90. data/lib/conceptql/operators/after.rb +20 -3
  91. data/lib/conceptql/operators/any_overlap.rb +3 -1
  92. data/lib/conceptql/operators/before.rb +19 -3
  93. data/lib/conceptql/operators/binary_operator_operator.rb +24 -20
  94. data/lib/conceptql/operators/casting_operator.rb +39 -31
  95. data/lib/conceptql/operators/co_reported.rb +42 -0
  96. data/lib/conceptql/operators/complement.rb +21 -16
  97. data/lib/conceptql/operators/concurrent_within.rb +57 -0
  98. data/lib/conceptql/operators/condition_occurrence_source_vocabulary_operator.rb +34 -0
  99. data/lib/conceptql/operators/condition_occurrence_source_vocabulary_operator_union.rb +28 -0
  100. data/lib/conceptql/operators/condition_type.rb +12 -4
  101. data/lib/conceptql/operators/contains.rb +6 -2
  102. data/lib/conceptql/operators/count.rb +10 -2
  103. data/lib/conceptql/operators/cpt.rb +5 -2
  104. data/lib/conceptql/operators/cpt_or_hcpcs.rb +27 -0
  105. data/lib/conceptql/operators/date_range.rb +20 -8
  106. data/lib/conceptql/operators/death.rb +4 -2
  107. data/lib/conceptql/operators/drg.rb +42 -0
  108. data/lib/conceptql/operators/drug_type_concept.rb +11 -2
  109. data/lib/conceptql/operators/during.rb +4 -2
  110. data/lib/conceptql/operators/equal.rb +4 -1
  111. data/lib/conceptql/operators/except.rb +16 -4
  112. data/lib/conceptql/operators/filter.rb +6 -3
  113. data/lib/conceptql/operators/first.rb +3 -1
  114. data/lib/conceptql/operators/from.rb +32 -5
  115. data/lib/conceptql/operators/from_seer_visits.rb +11 -5
  116. data/lib/conceptql/operators/gender.rb +9 -2
  117. data/lib/conceptql/operators/hcpcs.rb +5 -2
  118. data/lib/conceptql/operators/icd10.rb +6 -15
  119. data/lib/conceptql/operators/icd10_pcs.rb +28 -0
  120. data/lib/conceptql/operators/icd9.rb +6 -15
  121. data/lib/conceptql/operators/icd9_procedure.rb +5 -2
  122. data/lib/conceptql/operators/intersect.rb +15 -10
  123. data/lib/conceptql/operators/invalid.rb +36 -0
  124. data/lib/conceptql/operators/last.rb +3 -1
  125. data/lib/conceptql/operators/loinc.rb +5 -2
  126. data/lib/conceptql/operators/medcode.rb +5 -16
  127. data/lib/conceptql/operators/medcode_procedure.rb +3 -2
  128. data/lib/conceptql/operators/ndc.rb +5 -2
  129. data/lib/conceptql/operators/numeric.rb +30 -11
  130. data/lib/conceptql/operators/observation_by_enttype.rb +5 -2
  131. data/lib/conceptql/operators/observation_period.rb +6 -4
  132. data/lib/conceptql/operators/occurrence.rb +47 -11
  133. data/lib/conceptql/operators/one_in_two_out.rb +96 -33
  134. data/lib/conceptql/operators/operator.rb +628 -95
  135. data/lib/conceptql/operators/overlapped_by.rb +8 -5
  136. data/lib/conceptql/operators/overlaps.rb +7 -5
  137. data/lib/conceptql/operators/pass_thru.rb +12 -2
  138. data/lib/conceptql/operators/person.rb +7 -5
  139. data/lib/conceptql/operators/person_filter.rb +5 -1
  140. data/lib/conceptql/operators/place_of_service_code.rb +12 -5
  141. data/lib/conceptql/operators/place_of_service_filter.rb +47 -0
  142. data/lib/conceptql/operators/procedure_occurrence.rb +4 -2
  143. data/lib/conceptql/operators/prodcode.rb +5 -2
  144. data/lib/conceptql/operators/provenance.rb +66 -0
  145. data/lib/conceptql/operators/provider_filter.rb +36 -0
  146. data/lib/conceptql/operators/race.rb +11 -4
  147. data/lib/conceptql/operators/read.rb +149 -0
  148. data/lib/conceptql/operators/recall.rb +42 -7
  149. data/lib/conceptql/operators/revenue_code.rb +40 -0
  150. data/lib/conceptql/operators/rxnorm.rb +5 -1
  151. data/lib/conceptql/operators/snomed.rb +3 -2
  152. data/lib/conceptql/operators/source_vocabulary_operator.rb +44 -14
  153. data/lib/conceptql/operators/standard_vocabulary_operator.rb +36 -15
  154. data/lib/conceptql/operators/started_by.rb +2 -1
  155. data/lib/conceptql/operators/sum.rb +7 -1
  156. data/lib/conceptql/operators/temporal_operator.rb +75 -9
  157. data/lib/conceptql/operators/time_window.rb +13 -23
  158. data/lib/conceptql/operators/to_seer_visits.rb +6 -1
  159. data/lib/conceptql/operators/trim_date_end.rb +20 -12
  160. data/lib/conceptql/operators/trim_date_start.rb +22 -12
  161. data/lib/conceptql/operators/union.rb +39 -2
  162. data/lib/conceptql/operators/visit_occurrence.rb +5 -3
  163. data/lib/conceptql/operators/vocabulary_operator.rb +45 -0
  164. data/lib/conceptql/query.rb +68 -22
  165. data/lib/conceptql/query_modifiers/drug_query_modifier.rb +45 -0
  166. data/lib/conceptql/query_modifiers/pos_query_modifier.rb +31 -0
  167. data/lib/conceptql/query_modifiers/query_modifier.rb +16 -0
  168. data/lib/conceptql/scope.rb +169 -31
  169. data/lib/conceptql/sql_formatter.rb +22 -0
  170. data/lib/conceptql/version.rb +1 -1
  171. data/test/all.rb +3 -0
  172. data/test/all_operations_test.rb +45 -0
  173. data/test/code_list_test.rb +23 -0
  174. data/test/data/omopv4/care_site.csv +0 -0
  175. data/test/data/omopv4/cohort.csv +0 -0
  176. data/test/data/omopv4/condition_era.csv +0 -0
  177. data/test/data/omopv4/condition_occurrence.csv +34044 -0
  178. data/test/data/omopv4/death.csv +1 -0
  179. data/test/data/omopv4/drug_cost.csv +0 -0
  180. data/test/data/omopv4/drug_era.csv +0 -0
  181. data/test/data/omopv4/drug_exposure.csv +2 -0
  182. data/test/data/omopv4/location.csv +0 -0
  183. data/test/data/omopv4/observation.csv +2 -0
  184. data/test/data/omopv4/observation_period.csv +1 -0
  185. data/test/data/omopv4/organization.csv +0 -0
  186. data/test/data/omopv4/payer_plan_period.csv +0 -0
  187. data/test/data/omopv4/person.csv +250 -0
  188. data/test/data/omopv4/procedure_cost.csv +0 -0
  189. data/test/data/omopv4/procedure_occurrence.csv +35099 -0
  190. data/test/data/omopv4/provider.csv +0 -0
  191. data/test/data/omopv4/visit_occurrence.csv +14931 -0
  192. data/test/data/omopv4_plus/care_site.csv +0 -0
  193. data/test/data/omopv4_plus/cohort.csv +0 -0
  194. data/test/data/omopv4_plus/concept.csv +352 -0
  195. data/test/data/omopv4_plus/condition_era.csv +0 -0
  196. data/test/data/omopv4_plus/condition_occurrence.csv +46673 -0
  197. data/test/data/omopv4_plus/death.csv +9 -0
  198. data/test/data/omopv4_plus/drug_cost.csv +13921 -0
  199. data/test/data/omopv4_plus/drug_era.csv +0 -0
  200. data/test/data/omopv4_plus/drug_exposure.csv +13921 -0
  201. data/test/data/omopv4_plus/headers/care_site.csv +1 -0
  202. data/test/data/omopv4_plus/headers/cohort.csv +1 -0
  203. data/test/data/omopv4_plus/headers/concept.csv +1 -0
  204. data/test/data/omopv4_plus/headers/condition_era.csv +1 -0
  205. data/test/data/omopv4_plus/headers/condition_occurrence.csv +1 -0
  206. data/test/data/omopv4_plus/headers/death.csv +1 -0
  207. data/test/data/omopv4_plus/headers/drug_cost.csv +1 -0
  208. data/test/data/omopv4_plus/headers/drug_era.csv +1 -0
  209. data/test/data/omopv4_plus/headers/drug_exposure.csv +1 -0
  210. data/test/data/omopv4_plus/headers/location.csv +1 -0
  211. data/test/data/omopv4_plus/headers/observation.csv +1 -0
  212. data/test/data/omopv4_plus/headers/observation_period.csv +1 -0
  213. data/test/data/omopv4_plus/headers/organization.csv +1 -0
  214. data/test/data/omopv4_plus/headers/payer_plan_period.csv +1 -0
  215. data/test/data/omopv4_plus/headers/person.csv +1 -0
  216. data/test/data/omopv4_plus/headers/procedure_cost.csv +1 -0
  217. data/test/data/omopv4_plus/headers/procedure_occurrence.csv +1 -0
  218. data/test/data/omopv4_plus/headers/provider.csv +1 -0
  219. data/test/data/omopv4_plus/headers/source_to_concept_map.csv +1 -0
  220. data/test/data/omopv4_plus/headers/visit_occurrence.csv +1 -0
  221. data/test/data/omopv4_plus/headers/vocabulary.csv +1 -0
  222. data/test/data/omopv4_plus/location.csv +0 -0
  223. data/test/data/omopv4_plus/observation.csv +0 -0
  224. data/test/data/omopv4_plus/observation_period.csv +147 -0
  225. data/test/data/omopv4_plus/organization.csv +736 -0
  226. data/test/data/omopv4_plus/payer_plan_period.csv +808 -0
  227. data/test/data/omopv4_plus/person.csv +250 -0
  228. data/test/data/omopv4_plus/procedure_cost.csv +20123 -0
  229. data/test/data/omopv4_plus/procedure_occurrence.csv +27273 -0
  230. data/test/data/omopv4_plus/provider.csv +10193 -0
  231. data/test/data/omopv4_plus/source_to_concept_map.csv +285 -0
  232. data/test/data/omopv4_plus/visit_occurrence.csv +45125 -0
  233. data/test/data/omopv4_plus/vocabulary.csv +60 -0
  234. data/test/db.rb +15 -0
  235. data/test/db_setup.rb +408 -0
  236. data/test/db_teardown.rb +33 -0
  237. data/test/fake_annotater_test.rb +31 -0
  238. data/test/helper.rb +129 -0
  239. data/test/knitter/conceptql.md.cql +39 -0
  240. data/test/knitter/conceptql.md.expect +43 -0
  241. data/test/knitter/empty.md.cql +0 -0
  242. data/test/knitter/except.md.cql +13 -0
  243. data/test/knitter/except.md.expect +14 -0
  244. data/test/knitter/fake.md.cql +10 -0
  245. data/test/knitter/fake.md.expect +13 -0
  246. data/test/knitter/many.md.cql +7 -0
  247. data/test/knitter/many.md.expect +14 -0
  248. data/test/knitter/no_conceptql.md.cql +36 -0
  249. data/test/knitter/title.md.cql +12 -0
  250. data/test/knitter/title.md.expect +15 -0
  251. data/test/knitter/union.md.cql +11 -0
  252. data/test/knitter/union.md.expect +14 -0
  253. data/test/knitter_test.rb +69 -0
  254. data/test/query_test.rb +36 -0
  255. data/test/results/omopv4/after/anno_1 +25 -0
  256. data/test/results/omopv4/after/anno_2 +48 -0
  257. data/test/results/omopv4/after/anno_3 +34 -0
  258. data/test/results/omopv4/after/anno_4 +60 -0
  259. data/test/results/omopv4/after/anno_5 +68 -0
  260. data/test/results/omopv4/after/anno_6 +60 -0
  261. data/test/results/omopv4/after/crit_at_least +7 -0
  262. data/test/results/omopv4/after/crit_basic +32 -0
  263. data/test/results/omopv4/after/crit_occurrences +12 -0
  264. data/test/results/omopv4/after/crit_within +6 -0
  265. data/test/results/omopv4/any_overlap/crit_basic1 +15 -0
  266. data/test/results/omopv4/any_overlap/crit_basic2 +15 -0
  267. data/test/results/omopv4/any_overlap/crit_occurrences1 +2 -0
  268. data/test/results/omopv4/any_overlap/crit_occurrences2 +15 -0
  269. data/test/results/omopv4/any_overlap/crit_within +8 -0
  270. data/test/results/omopv4/before/crit_at_least +6 -0
  271. data/test/results/omopv4/before/crit_basic1 +48 -0
  272. data/test/results/omopv4/before/crit_basic2 +7 -0
  273. data/test/results/omopv4/before/crit_occurrences +13 -0
  274. data/test/results/omopv4/before/crit_within +18 -0
  275. data/test/results/omopv4/co_reported/anno_1 +43 -0
  276. data/test/results/omopv4/co_reported/anno_2 +66 -0
  277. data/test/results/omopv4/complement/anno_duplicate_params +52 -0
  278. data/test/results/omopv4/complement/anno_invalid_params +37 -0
  279. data/test/results/omopv4/complement/anno_no_params +18 -0
  280. data/test/results/omopv4/complement/count_3way_intersect +4 -0
  281. data/test/results/omopv4/complement/count_3way_union +4 -0
  282. data/test/results/omopv4/complement/count_intersect +3 -0
  283. data/test/results/omopv4/complement/count_union +3 -0
  284. data/test/results/omopv4/complement/count_union_and_intersect +4 -0
  285. data/test/results/omopv4/complement/crit_3way_intersect +1 -0
  286. data/test/results/omopv4/complement/crit_3way_union +1 -0
  287. data/test/results/omopv4/complement/crit_basic1 +33998 -0
  288. data/test/results/omopv4/complement/crit_icd9_selector +54 -0
  289. data/test/results/omopv4/complement/crit_intersect +1 -0
  290. data/test/results/omopv4/complement/crit_union +1 -0
  291. data/test/results/omopv4/complement/crit_union_and_intersect +1 -0
  292. data/test/results/omopv4/complex/anno_1 +85 -0
  293. data/test/results/omopv4/complex/crit_1 +2 -0
  294. data/test/results/omopv4/complex/crit_2 +2 -0
  295. data/test/results/omopv4/complex/crit_3 +2 -0
  296. data/test/results/omopv4/complex/crit_4 +5 -0
  297. data/test/results/omopv4/complex/crit_5 +6 -0
  298. data/test/results/omopv4/complex/crit_6 +28 -0
  299. data/test/results/omopv4/complex/crit_7 +46 -0
  300. data/test/results/omopv4/complex/crit_out_of_order_ctes +7 -0
  301. data/test/results/omopv4/complex/scanno_1 +3 -0
  302. data/test/results/omopv4/concurrent_within/crit_icd9 +54 -0
  303. data/test/results/omopv4/concurrent_within/crit_icd9_and_place_of_service +23 -0
  304. data/test/results/omopv4/concurrent_within/crit_negative_start +5 -0
  305. data/test/results/omopv4/condition_type/anno_icd9 +39 -0
  306. data/test/results/omopv4/condition_type/count_condition_era +2 -0
  307. data/test/results/omopv4/condition_type/count_condition_era_30_day_window +2 -0
  308. data/test/results/omopv4/condition_type/count_ehr_problem_list +2 -0
  309. data/test/results/omopv4/condition_type/count_era_0 +2 -0
  310. data/test/results/omopv4/condition_type/count_inpatient +3 -0
  311. data/test/results/omopv4/condition_type/count_inpatient_detail +2 -0
  312. data/test/results/omopv4/condition_type/count_inpatient_header +3 -0
  313. data/test/results/omopv4/condition_type/count_inpatient_header_2 +3 -0
  314. data/test/results/omopv4/condition_type/count_inpatient_header_3 +3 -0
  315. data/test/results/omopv4/condition_type/count_inpatient_header_4 +3 -0
  316. data/test/results/omopv4/condition_type/count_inpatient_header_5 +3 -0
  317. data/test/results/omopv4/condition_type/count_inpatient_outpatient_detail +3 -0
  318. data/test/results/omopv4/condition_type/count_inpatient_primary +2 -0
  319. data/test/results/omopv4/condition_type/count_inpatient_primary_or_first +3 -0
  320. data/test/results/omopv4/condition_type/count_outpatient +3 -0
  321. data/test/results/omopv4/condition_type/count_outpatient_detail +3 -0
  322. data/test/results/omopv4/condition_type/count_outpatient_header +2 -0
  323. data/test/results/omopv4/condition_type/count_outpatient_primary +3 -0
  324. data/test/results/omopv4/condition_type/count_primary +3 -0
  325. data/test/results/omopv4/condition_type/crit_condition_era +1 -0
  326. data/test/results/omopv4/condition_type/crit_condition_era_30_day_window +1 -0
  327. data/test/results/omopv4/condition_type/crit_ehr_problem_list +1 -0
  328. data/test/results/omopv4/condition_type/crit_era_0 +1 -0
  329. data/test/results/omopv4/condition_type/crit_inpatient +1 -0
  330. data/test/results/omopv4/condition_type/crit_inpatient_detail +1 -0
  331. data/test/results/omopv4/condition_type/crit_inpatient_header +1 -0
  332. data/test/results/omopv4/condition_type/crit_inpatient_header_2 +1 -0
  333. data/test/results/omopv4/condition_type/crit_inpatient_header_3 +1 -0
  334. data/test/results/omopv4/condition_type/crit_inpatient_header_4 +1 -0
  335. data/test/results/omopv4/condition_type/crit_inpatient_header_5 +1 -0
  336. data/test/results/omopv4/condition_type/crit_inpatient_primary +1 -0
  337. data/test/results/omopv4/condition_type/crit_inpatient_primary_or_first +1 -0
  338. data/test/results/omopv4/condition_type/crit_outpatient +1 -0
  339. data/test/results/omopv4/condition_type/crit_outpatient_detail +1 -0
  340. data/test/results/omopv4/condition_type/crit_outpatient_header +1 -0
  341. data/test/results/omopv4/condition_type/crit_outpatient_primary +1 -0
  342. data/test/results/omopv4/condition_type/crit_primary +1 -0
  343. data/test/results/omopv4/contains/crit_1 +5 -0
  344. data/test/results/omopv4/contains/crit_2 +2 -0
  345. data/test/results/omopv4/contains/crit_3 +2 -0
  346. data/test/results/omopv4/count/anno_multiple_upstreams +52 -0
  347. data/test/results/omopv4/count/anno_no_upstream1 +18 -0
  348. data/test/results/omopv4/count/anno_no_upstream2 +25 -0
  349. data/test/results/omopv4/count/crit_icd9_ndc +8 -0
  350. data/test/results/omopv4/count/crit_ndc +5 -0
  351. data/test/results/omopv4/count/crit_person +254 -0
  352. data/test/results/omopv4/cpt/anno_icd9_upstream +40 -0
  353. data/test/results/omopv4/cpt/anno_invalid_code +22 -0
  354. data/test/results/omopv4/cpt/count_1 +3 -0
  355. data/test/results/omopv4/cpt/crit_1 +174 -0
  356. data/test/results/omopv4/cpt/crit_2 +1 -0
  357. data/test/results/omopv4/cpt/scanno_1 +17 -0
  358. data/test/results/omopv4/cpt_or_hcpcs/anno_bad_format +25 -0
  359. data/test/results/omopv4/cpt_or_hcpcs/count_1 +3 -0
  360. data/test/results/omopv4/cpt_or_hcpcs/crit_1 +179 -0
  361. data/test/results/omopv4/cpt_or_hcpcs/crit_2 +1 -0
  362. data/test/results/omopv4/date_range/anno_1 +15 -0
  363. data/test/results/omopv4/date_range/anno_extra_argument +24 -0
  364. data/test/results/omopv4/date_range/anno_invalid_argument +25 -0
  365. data/test/results/omopv4/date_range/anno_missing_argument1 +20 -0
  366. data/test/results/omopv4/date_range/anno_missing_argument2 +20 -0
  367. data/test/results/omopv4/date_range/anno_no_upstreams +38 -0
  368. data/test/results/omopv4/date_range/count_1 +3 -0
  369. data/test/results/omopv4/date_range/count_2 +3 -0
  370. data/test/results/omopv4/date_range/crit_1 +1 -0
  371. data/test/results/omopv4/date_range/crit_2 +1 -0
  372. data/test/results/omopv4/death/anno_multiple_upstreams +50 -0
  373. data/test/results/omopv4/death/anno_no_upstreams +22 -0
  374. data/test/results/omopv4/death/crit_basic +5 -0
  375. data/test/results/omopv4/death/crit_person +5 -0
  376. data/test/results/omopv4/drug_type_concept/anno_has_upstreams +37 -0
  377. data/test/results/omopv4/drug_type_concept/anno_no_arguments +18 -0
  378. data/test/results/omopv4/drug_type_concept/crit_basic1 +5 -0
  379. data/test/results/omopv4/drug_type_concept/crit_basic2 +2 -0
  380. data/test/results/omopv4/during/crit_1 +15 -0
  381. data/test/results/omopv4/during/crit_2 +2 -0
  382. data/test/results/omopv4/equal/crit_1 +5 -0
  383. data/test/results/omopv4/equal/crit_2 +5 -0
  384. data/test/results/omopv4/except/anno_1 +42 -0
  385. data/test/results/omopv4/except/anno_2 +43 -0
  386. data/test/results/omopv4/except/count_complex +5 -0
  387. data/test/results/omopv4/except/crit_412_cpt +54 -0
  388. data/test/results/omopv4/except/crit_412_inpatient +46 -0
  389. data/test/results/omopv4/except/crit_complex +1 -0
  390. data/test/results/omopv4/filter/crit_1 +54 -0
  391. data/test/results/omopv4/first/anno_argument +25 -0
  392. data/test/results/omopv4/first/anno_no_upstream +18 -0
  393. data/test/results/omopv4/first/crit_cpt +207 -0
  394. data/test/results/omopv4/first/crit_icd9 +42 -0
  395. data/test/results/omopv4/first/crit_union +45 -0
  396. data/test/results/omopv4/from/anno_has_upstreams +39 -0
  397. data/test/results/omopv4/from/anno_multiple_arguments +24 -0
  398. data/test/results/omopv4/from/count_condition_occurrence +3 -0
  399. data/test/results/omopv4/from/count_observation_period +3 -0
  400. data/test/results/omopv4/from/count_person +3 -0
  401. data/test/results/omopv4/from_seer_visits/anno_multiple_upstreams +78 -0
  402. data/test/results/omopv4/from_seer_visits/anno_no_upstream +18 -0
  403. data/test/results/omopv4/from_seer_visits/crit_1 +6 -0
  404. data/test/results/omopv4/from_seer_visits/crit_2 +5 -0
  405. data/test/results/omopv4/from_seer_visits/crit_3 +5 -0
  406. data/test/results/omopv4/from_seer_visits/crit_4 +6 -0
  407. data/test/results/omopv4/gender/anno_has_upstreams +39 -0
  408. data/test/results/omopv4/gender/crit_male +130 -0
  409. data/test/results/omopv4/hcpcs/anno_bad_format +24 -0
  410. data/test/results/omopv4/hcpcs/crit_A0382 +9 -0
  411. data/test/results/omopv4/icd10/anno_bad_format +22 -0
  412. data/test/results/omopv4/icd10/anno_has_upstreams +40 -0
  413. data/test/results/omopv4/icd10/crit_1 +5 -0
  414. data/test/results/omopv4/icd10pcs/anno_bad_format +28 -0
  415. data/test/results/omopv4/icd10pcs/anno_has_upstreams +40 -0
  416. data/test/results/omopv4/icd10pcs/crit_1 +2 -0
  417. data/test/results/omopv4/icd9/anno_empty_label +15 -0
  418. data/test/results/omopv4/icd9/anno_invalid_code +21 -0
  419. data/test/results/omopv4/icd9/crit_1 +54 -0
  420. data/test/results/omopv4/icd9_procedure/crit_1 +5 -0
  421. data/test/results/omopv4/intersect/anno_412_inpatient +42 -0
  422. data/test/results/omopv4/intersect/anno_has_arguments +25 -0
  423. data/test/results/omopv4/intersect/anno_no_upstream +18 -0
  424. data/test/results/omopv4/intersect/crit_412_inpatient +12 -0
  425. data/test/results/omopv4/intersect/crit_412_male +182 -0
  426. data/test/results/omopv4/intersect/crit_complex +118 -0
  427. data/test/results/omopv4/invalid/anno_bad_op +55 -0
  428. data/test/results/omopv4/invalid/scanno_1 +23 -0
  429. data/test/results/omopv4/last/crit_icd9 +42 -0
  430. data/test/results/omopv4/loinc/crit_basic +5 -0
  431. data/test/results/omopv4/ndc/crit_basic +5 -0
  432. data/test/results/omopv4/numeric/anno_multiple_upstreams +59 -0
  433. data/test/results/omopv4/numeric/num_values_1 +254 -0
  434. data/test/results/omopv4/numeric/num_values_2 +5 -0
  435. data/test/results/omopv4/numeric/num_values_3 +5 -0
  436. data/test/results/omopv4/observation_period/anno_has_arguments +36 -0
  437. data/test/results/omopv4/observation_period/anno_multiple_upstreams +51 -0
  438. data/test/results/omopv4/observation_period/count_all_periods +3 -0
  439. data/test/results/omopv4/observation_period/crit_female +2 -0
  440. data/test/results/omopv4/observation_period/crit_icd9 +5 -0
  441. data/test/results/omopv4/observation_period/crit_male +5 -0
  442. data/test/results/omopv4/occurrence/anno_no_upstream +22 -0
  443. data/test/results/omopv4/occurrence/cc_412_410 +1 -0
  444. data/test/results/omopv4/occurrence/count_412_410 +3 -0
  445. data/test/results/omopv4/occurrence/crit_1 +16 -0
  446. data/test/results/omopv4/occurrence/crit_2 +2 -0
  447. data/test/results/omopv4/occurrence/crit_3 +42 -0
  448. data/test/results/omopv4/one_in_two_out/anno_has_arguments +27 -0
  449. data/test/results/omopv4/one_in_two_out/anno_multiple_upstreams +54 -0
  450. data/test/results/omopv4/one_in_two_out/anno_no_upstream +20 -0
  451. data/test/results/omopv4/one_in_two_out/count_1 +3 -0
  452. data/test/results/omopv4/one_in_two_out/crit_hcpcs +7 -0
  453. data/test/results/omopv4/one_in_two_out/crit_icd9 +21 -0
  454. data/test/results/omopv4/overlapped_by/crit_1 +5 -0
  455. data/test/results/omopv4/overlapped_by/crit_2 +2 -0
  456. data/test/results/omopv4/overlapped_by/crit_3 +5 -0
  457. data/test/results/omopv4/overlapped_by/crit_4 +2 -0
  458. data/test/results/omopv4/overlaps/crit_1 +5 -0
  459. data/test/results/omopv4/overlaps/crit_2 +2 -0
  460. data/test/results/omopv4/overlaps/crit_3 +5 -0
  461. data/test/results/omopv4/overlaps/crit_4 +2 -0
  462. data/test/results/omopv4/person/anno_has_arguments +22 -0
  463. data/test/results/omopv4/person/anno_multiple_upstreams +52 -0
  464. data/test/results/omopv4/person/count_2 +3 -0
  465. data/test/results/omopv4/person/crit_1 +42 -0
  466. data/test/results/omopv4/person/crit_2 +1 -0
  467. data/test/results/omopv4/person_filter/count_1 +4 -0
  468. data/test/results/omopv4/person_filter/crit_1 +54 -0
  469. data/test/results/omopv4/person_filter/crit_2 +5 -0
  470. data/test/results/omopv4/person_filter/crit_3 +32 -0
  471. data/test/results/omopv4/person_filter/crit_4 +52 -0
  472. data/test/results/omopv4/person_filter/crit_5 +1 -0
  473. data/test/results/omopv4/place_of_service_code/anno_has_upstreams +37 -0
  474. data/test/results/omopv4/place_of_service_code/anno_no_arguments +18 -0
  475. data/test/results/omopv4/place_of_service_code/crit_basic +174 -0
  476. data/test/results/omopv4/place_of_service_filter/anno_1 +29 -0
  477. data/test/results/omopv4/procedure_occurrence/anno_has_arguments +37 -0
  478. data/test/results/omopv4/procedure_occurrence/anno_multiple_upstreams +51 -0
  479. data/test/results/omopv4/procedure_occurrence/count_gender +3 -0
  480. data/test/results/omopv4/procedure_occurrence/count_icd9 +3 -0
  481. data/test/results/omopv4/procedure_occurrence/count_started_by +3 -0
  482. data/test/results/omopv4/procedure_occurrence/crit_gender +1 -0
  483. data/test/results/omopv4/procedure_occurrence/crit_icd9 +1 -0
  484. data/test/results/omopv4/procedure_occurrence/crit_started_by +1 -0
  485. data/test/results/omopv4/provenance/anno_1 +29 -0
  486. data/test/results/omopv4/provider_filter/anno_1 +29 -0
  487. data/test/results/omopv4/race/anno_1 +37 -0
  488. data/test/results/omopv4/race/anno_2 +18 -0
  489. data/test/results/omopv4/race/crit_1 +28 -0
  490. data/test/results/omopv4/read/anno_1 +21 -0
  491. data/test/results/omopv4/read/crit_1 +2 -0
  492. data/test/results/omopv4/recall/anno_1 +54 -0
  493. data/test/results/omopv4/recall/anno_2 +66 -0
  494. data/test/results/omopv4/recall/anno_3 +20 -0
  495. data/test/results/omopv4/recall/anno_4 +18 -0
  496. data/test/results/omopv4/recall/anno_5 +24 -0
  497. data/test/results/omopv4/recall/anno_6 +270 -0
  498. data/test/results/omopv4/recall/crit_1 +21 -0
  499. data/test/results/omopv4/recall/crit_2 +54 -0
  500. data/test/results/omopv4/recall/crit_3 +2 -0
  501. data/test/results/omopv4/recall/crit_cte_1 +42 -0
  502. data/test/results/omopv4/recall/crit_cte_2 +42 -0
  503. data/test/results/omopv4/recall/crit_nested_perm_0 +54 -0
  504. data/test/results/omopv4/revenue_code/crit_1 +2 -0
  505. data/test/results/omopv4/revenue_code/crit_basic +2 -0
  506. data/test/results/omopv4/revenue_code/domains_1 +3 -0
  507. data/test/results/omopv4/revenue_code/domains_drg100 +3 -0
  508. data/test/results/omopv4/rxnorm/crit_1 +5 -0
  509. data/test/results/omopv4/snomed/crit_1 +84 -0
  510. data/test/results/omopv4/started_by/crit_1 +5 -0
  511. data/test/results/omopv4/started_by/crit_2 +2 -0
  512. data/test/results/omopv4/started_by/crit_3 +2 -0
  513. data/test/results/omopv4/sum/anno_1 +18 -0
  514. data/test/results/omopv4/sum/anno_2 +36 -0
  515. data/test/results/omopv4/sum/num_1 +5 -0
  516. data/test/results/omopv4/sum/num_2 +8 -0
  517. data/test/results/omopv4/sum/num_3 +254 -0
  518. data/test/results/omopv4/time_window/anno_1 +20 -0
  519. data/test/results/omopv4/time_window/anno_2 +40 -0
  520. data/test/results/omopv4/time_window/anno_3 +36 -0
  521. data/test/results/omopv4/time_window/anno_4 +39 -0
  522. data/test/results/omopv4/time_window/anno_5 +57 -0
  523. data/test/results/omopv4/time_window/crit_1 +54 -0
  524. data/test/results/omopv4/time_window/crit_2 +174 -0
  525. data/test/results/omopv4/time_window/crit_3 +54 -0
  526. data/test/results/omopv4/time_window/crit_4 +174 -0
  527. data/test/results/omopv4/trim_date_end/crit_1 +5 -0
  528. data/test/results/omopv4/trim_date_end/crit_2 +2 -0
  529. data/test/results/omopv4/trim_date_end/crit_3 +6 -0
  530. data/test/results/omopv4/trim_date_end/crit_at_least +5 -0
  531. data/test/results/omopv4/trim_date_end/crit_occurrences_1 +2 -0
  532. data/test/results/omopv4/trim_date_end/crit_occurrences_2 +6 -0
  533. data/test/results/omopv4/trim_date_end/crit_within +5 -0
  534. data/test/results/omopv4/trim_date_start/crit_1 +5 -0
  535. data/test/results/omopv4/trim_date_start/crit_2 +2 -0
  536. data/test/results/omopv4/trim_date_start/crit_3 +6 -0
  537. data/test/results/omopv4/trim_date_start/crit_at_least +5 -0
  538. data/test/results/omopv4/trim_date_start/crit_occurrences_1 +2 -0
  539. data/test/results/omopv4/trim_date_start/crit_occurrences_2 +6 -0
  540. data/test/results/omopv4/trim_date_start/crit_within +5 -0
  541. data/test/results/omopv4/union/anno_1 +43 -0
  542. data/test/results/omopv4/union/anno_2 +74 -0
  543. data/test/results/omopv4/union/anno_3 +18 -0
  544. data/test/results/omopv4/union/anno_4 +25 -0
  545. data/test/results/omopv4/union/anno_5 +33 -0
  546. data/test/results/omopv4/union/anno_6 +46 -0
  547. data/test/results/omopv4/union/cc_1 +1 -0
  548. data/test/results/omopv4/union/cc_2 +1 -0
  549. data/test/results/omopv4/union/cc_3 +1 -0
  550. data/test/results/omopv4/union/cc_4 +1 -0
  551. data/test/results/omopv4/union/cc_5 +1 -0
  552. data/test/results/omopv4/union/count_1 +3 -0
  553. data/test/results/omopv4/union/count_2 +3 -0
  554. data/test/results/omopv4/union/count_3 +3 -0
  555. data/test/results/omopv4/union/count_4 +3 -0
  556. data/test/results/omopv4/union/count_5 +4 -0
  557. data/test/results/omopv4/union/scanno_1 +22 -0
  558. data/test/results/omopv4/union/scanno_2 +36 -0
  559. data/test/results/omopv4/visit_occurrence/anno_1 +52 -0
  560. data/test/results/omopv4/visit_occurrence/anno_2 +37 -0
  561. data/test/results/omopv4/visit_occurrence/crit_1 +54 -0
  562. data/test/results/omopv4/visit_occurrence/crit_2 +7566 -0
  563. data/test/results/omopv4/visit_occurrence/crit_3 +14935 -0
  564. data/test/results/omopv4_plus/after/anno_1 +25 -0
  565. data/test/results/omopv4_plus/after/anno_2 +48 -0
  566. data/test/results/omopv4_plus/after/anno_3 +34 -0
  567. data/test/results/omopv4_plus/after/anno_4 +60 -0
  568. data/test/results/omopv4_plus/after/anno_5 +68 -0
  569. data/test/results/omopv4_plus/after/anno_6 +60 -0
  570. data/test/results/omopv4_plus/after/crit_at_least +7 -0
  571. data/test/results/omopv4_plus/after/crit_basic +32 -0
  572. data/test/results/omopv4_plus/after/crit_occurrences +12 -0
  573. data/test/results/omopv4_plus/after/crit_within +5 -0
  574. data/test/results/omopv4_plus/any_overlap/crit_basic1 +14 -0
  575. data/test/results/omopv4_plus/any_overlap/crit_basic2 +14 -0
  576. data/test/results/omopv4_plus/any_overlap/crit_occurrences1 +2 -0
  577. data/test/results/omopv4_plus/any_overlap/crit_occurrences2 +14 -0
  578. data/test/results/omopv4_plus/any_overlap/crit_within +8 -0
  579. data/test/results/omopv4_plus/before/crit_at_least +6 -0
  580. data/test/results/omopv4_plus/before/crit_basic1 +48 -0
  581. data/test/results/omopv4_plus/before/crit_basic2 +8 -0
  582. data/test/results/omopv4_plus/before/crit_occurrences +13 -0
  583. data/test/results/omopv4_plus/before/crit_within +17 -0
  584. data/test/results/omopv4_plus/co_reported/anno_1 +43 -0
  585. data/test/results/omopv4_plus/co_reported/anno_2 +66 -0
  586. data/test/results/omopv4_plus/co_reported/anno_3 +47 -0
  587. data/test/results/omopv4_plus/complement/anno_duplicate_params +52 -0
  588. data/test/results/omopv4_plus/complement/anno_invalid_params +37 -0
  589. data/test/results/omopv4_plus/complement/anno_no_params +18 -0
  590. data/test/results/omopv4_plus/complement/count_3way_intersect +4 -0
  591. data/test/results/omopv4_plus/complement/count_3way_union +4 -0
  592. data/test/results/omopv4_plus/complement/count_intersect +3 -0
  593. data/test/results/omopv4_plus/complement/count_union +3 -0
  594. data/test/results/omopv4_plus/complement/count_union_and_intersect +4 -0
  595. data/test/results/omopv4_plus/complement/crit_basic1 +52483 -0
  596. data/test/results/omopv4_plus/complement/crit_icd9_selector +52 -0
  597. data/test/results/omopv4_plus/complex/anno_1 +85 -0
  598. data/test/results/omopv4_plus/complex/crit_1 +2 -0
  599. data/test/results/omopv4_plus/complex/crit_2 +2 -0
  600. data/test/results/omopv4_plus/complex/crit_3 +2 -0
  601. data/test/results/omopv4_plus/complex/crit_4 +2 -0
  602. data/test/results/omopv4_plus/complex/crit_5 +2 -0
  603. data/test/results/omopv4_plus/complex/crit_6 +24 -0
  604. data/test/results/omopv4_plus/complex/crit_7 +45 -0
  605. data/test/results/omopv4_plus/complex/crit_out_of_order_ctes +15 -0
  606. data/test/results/omopv4_plus/complex/scanno_1 +108 -0
  607. data/test/results/omopv4_plus/concurrent_within/crit_icd9 +52 -0
  608. data/test/results/omopv4_plus/concurrent_within/crit_icd9_and_place_of_service +21 -0
  609. data/test/results/omopv4_plus/concurrent_within/crit_negative_start +5 -0
  610. data/test/results/omopv4_plus/condition_type/anno_icd9 +39 -0
  611. data/test/results/omopv4_plus/condition_type/count_condition_era +2 -0
  612. data/test/results/omopv4_plus/condition_type/count_condition_era_30_day_window +2 -0
  613. data/test/results/omopv4_plus/condition_type/count_ehr_problem_list +2 -0
  614. data/test/results/omopv4_plus/condition_type/count_era_0 +2 -0
  615. data/test/results/omopv4_plus/condition_type/count_inpatient +3 -0
  616. data/test/results/omopv4_plus/condition_type/count_inpatient_detail +2 -0
  617. data/test/results/omopv4_plus/condition_type/count_inpatient_header +3 -0
  618. data/test/results/omopv4_plus/condition_type/count_inpatient_header_2 +3 -0
  619. data/test/results/omopv4_plus/condition_type/count_inpatient_header_3 +3 -0
  620. data/test/results/omopv4_plus/condition_type/count_inpatient_header_4 +3 -0
  621. data/test/results/omopv4_plus/condition_type/count_inpatient_header_5 +3 -0
  622. data/test/results/omopv4_plus/condition_type/count_inpatient_outpatient_detail +3 -0
  623. data/test/results/omopv4_plus/condition_type/count_inpatient_primary +3 -0
  624. data/test/results/omopv4_plus/condition_type/count_inpatient_primary_or_first +3 -0
  625. data/test/results/omopv4_plus/condition_type/count_outpatient +3 -0
  626. data/test/results/omopv4_plus/condition_type/count_outpatient_detail +2 -0
  627. data/test/results/omopv4_plus/condition_type/count_outpatient_header +3 -0
  628. data/test/results/omopv4_plus/condition_type/count_outpatient_primary +3 -0
  629. data/test/results/omopv4_plus/condition_type/count_primary +3 -0
  630. data/test/results/omopv4_plus/contains/crit_1 +5 -0
  631. data/test/results/omopv4_plus/contains/crit_2 +2 -0
  632. data/test/results/omopv4_plus/contains/crit_3 +2 -0
  633. data/test/results/omopv4_plus/count/anno_multiple_upstreams +52 -0
  634. data/test/results/omopv4_plus/count/anno_no_upstream1 +18 -0
  635. data/test/results/omopv4_plus/count/anno_no_upstream2 +25 -0
  636. data/test/results/omopv4_plus/count/crit_icd9_ndc +5 -0
  637. data/test/results/omopv4_plus/count/crit_ndc +2 -0
  638. data/test/results/omopv4_plus/count/crit_person +254 -0
  639. data/test/results/omopv4_plus/cpt/anno_icd9_upstream +40 -0
  640. data/test/results/omopv4_plus/cpt/anno_invalid_code +22 -0
  641. data/test/results/omopv4_plus/cpt/count_1 +3 -0
  642. data/test/results/omopv4_plus/cpt/crit_1 +158 -0
  643. data/test/results/omopv4_plus/cpt/scanno_1 +17 -0
  644. data/test/results/omopv4_plus/cpt_or_hcpcs/anno_bad_format +25 -0
  645. data/test/results/omopv4_plus/cpt_or_hcpcs/count_1 +3 -0
  646. data/test/results/omopv4_plus/cpt_or_hcpcs/crit_1 +161 -0
  647. data/test/results/omopv4_plus/date_range/anno_1 +15 -0
  648. data/test/results/omopv4_plus/date_range/anno_extra_argument +24 -0
  649. data/test/results/omopv4_plus/date_range/anno_invalid_argument +25 -0
  650. data/test/results/omopv4_plus/date_range/anno_missing_argument1 +20 -0
  651. data/test/results/omopv4_plus/date_range/anno_missing_argument2 +20 -0
  652. data/test/results/omopv4_plus/date_range/anno_no_upstreams +38 -0
  653. data/test/results/omopv4_plus/date_range/count_1 +3 -0
  654. data/test/results/omopv4_plus/date_range/count_2 +3 -0
  655. data/test/results/omopv4_plus/death/anno_multiple_upstreams +50 -0
  656. data/test/results/omopv4_plus/death/anno_no_upstreams +22 -0
  657. data/test/results/omopv4_plus/death/crit_basic +14 -0
  658. data/test/results/omopv4_plus/death/crit_person +14 -0
  659. data/test/results/omopv4_plus/drug_type_concept/anno_has_upstreams +37 -0
  660. data/test/results/omopv4_plus/drug_type_concept/anno_no_arguments +18 -0
  661. data/test/results/omopv4_plus/drug_type_concept/crit_basic1 +2 -0
  662. data/test/results/omopv4_plus/drug_type_concept/crit_basic2 +2 -0
  663. data/test/results/omopv4_plus/during/crit_1 +14 -0
  664. data/test/results/omopv4_plus/during/crit_2 +2 -0
  665. data/test/results/omopv4_plus/equal/crit_1 +2 -0
  666. data/test/results/omopv4_plus/equal/crit_2 +2 -0
  667. data/test/results/omopv4_plus/except/anno_1 +42 -0
  668. data/test/results/omopv4_plus/except/anno_2 +43 -0
  669. data/test/results/omopv4_plus/except/count_complex +5 -0
  670. data/test/results/omopv4_plus/except/crit_412_cpt +52 -0
  671. data/test/results/omopv4_plus/except/crit_412_inpatient +45 -0
  672. data/test/results/omopv4_plus/filter/crit_1 +52 -0
  673. data/test/results/omopv4_plus/first/anno_argument +25 -0
  674. data/test/results/omopv4_plus/first/anno_no_upstream +18 -0
  675. data/test/results/omopv4_plus/first/crit_cpt +180 -0
  676. data/test/results/omopv4_plus/first/crit_icd9 +41 -0
  677. data/test/results/omopv4_plus/first/crit_union +52 -0
  678. data/test/results/omopv4_plus/from/anno_has_upstreams +39 -0
  679. data/test/results/omopv4_plus/from/anno_multiple_arguments +24 -0
  680. data/test/results/omopv4_plus/from/count_condition_occurrence +3 -0
  681. data/test/results/omopv4_plus/from/count_observation_period +3 -0
  682. data/test/results/omopv4_plus/from/count_person +3 -0
  683. data/test/results/omopv4_plus/from_seer_visits/anno_multiple_upstreams +78 -0
  684. data/test/results/omopv4_plus/from_seer_visits/anno_no_upstream +18 -0
  685. data/test/results/omopv4_plus/from_seer_visits/crit_1 +2 -0
  686. data/test/results/omopv4_plus/from_seer_visits/crit_2 +2 -0
  687. data/test/results/omopv4_plus/from_seer_visits/crit_3 +2 -0
  688. data/test/results/omopv4_plus/from_seer_visits/crit_4 +2 -0
  689. data/test/results/omopv4_plus/gender/anno_has_upstreams +39 -0
  690. data/test/results/omopv4_plus/gender/crit_male +128 -0
  691. data/test/results/omopv4_plus/hcpcs/anno_bad_format +24 -0
  692. data/test/results/omopv4_plus/hcpcs/crit_A0382 +7 -0
  693. data/test/results/omopv4_plus/icd10/anno_bad_format +22 -0
  694. data/test/results/omopv4_plus/icd10/anno_has_upstreams +40 -0
  695. data/test/results/omopv4_plus/icd10/crit_1 +2 -0
  696. data/test/results/omopv4_plus/icd10pcs/anno_bad_format +28 -0
  697. data/test/results/omopv4_plus/icd10pcs/anno_has_upstreams +40 -0
  698. data/test/results/omopv4_plus/icd10pcs/crit_1 +2 -0
  699. data/test/results/omopv4_plus/icd9/anno_empty_label +15 -0
  700. data/test/results/omopv4_plus/icd9/anno_invalid_code +21 -0
  701. data/test/results/omopv4_plus/icd9/anno_valid_code +3 -0
  702. data/test/results/omopv4_plus/icd9/crit_1 +52 -0
  703. data/test/results/omopv4_plus/icd9_procedure/crit_1 +5 -0
  704. data/test/results/omopv4_plus/intersect/anno_412_inpatient +42 -0
  705. data/test/results/omopv4_plus/intersect/anno_has_arguments +25 -0
  706. data/test/results/omopv4_plus/intersect/anno_no_upstream +18 -0
  707. data/test/results/omopv4_plus/intersect/crit_412_inpatient +11 -0
  708. data/test/results/omopv4_plus/intersect/crit_412_male +178 -0
  709. data/test/results/omopv4_plus/intersect/crit_complex +110 -0
  710. data/test/results/omopv4_plus/invalid/anno_bad_op +55 -0
  711. data/test/results/omopv4_plus/invalid/scanno_1 +23 -0
  712. data/test/results/omopv4_plus/last/crit_icd9 +41 -0
  713. data/test/results/omopv4_plus/loinc/crit_basic +2 -0
  714. data/test/results/omopv4_plus/ndc/crit_basic +2 -0
  715. data/test/results/omopv4_plus/ndc/results_1 +41 -0
  716. data/test/results/omopv4_plus/numeric/anno_multiple_upstreams +59 -0
  717. data/test/results/omopv4_plus/numeric/num_values_1 +254 -0
  718. data/test/results/omopv4_plus/numeric/num_values_2 +5 -0
  719. data/test/results/omopv4_plus/numeric/num_values_3 +5 -0
  720. data/test/results/omopv4_plus/observation_period/anno_has_arguments +36 -0
  721. data/test/results/omopv4_plus/observation_period/anno_multiple_upstreams +51 -0
  722. data/test/results/omopv4_plus/observation_period/count_all_periods +3 -0
  723. data/test/results/omopv4_plus/observation_period/crit_female +87 -0
  724. data/test/results/omopv4_plus/observation_period/crit_icd9 +28 -0
  725. data/test/results/omopv4_plus/observation_period/crit_male +75 -0
  726. data/test/results/omopv4_plus/occurrence/anno_no_upstream +22 -0
  727. data/test/results/omopv4_plus/occurrence/count_412_410 +3 -0
  728. data/test/results/omopv4_plus/occurrence/crit_1 +15 -0
  729. data/test/results/omopv4_plus/occurrence/crit_2 +2 -0
  730. data/test/results/omopv4_plus/occurrence/crit_3 +41 -0
  731. data/test/results/omopv4_plus/one_in_two_out/anno_has_arguments +27 -0
  732. data/test/results/omopv4_plus/one_in_two_out/anno_multiple_upstreams +54 -0
  733. data/test/results/omopv4_plus/one_in_two_out/anno_no_upstream +20 -0
  734. data/test/results/omopv4_plus/one_in_two_out/count_1 +3 -0
  735. data/test/results/omopv4_plus/one_in_two_out/count_same_as_1 +3 -0
  736. data/test/results/omopv4_plus/one_in_two_out/crit_hcpcs +2 -0
  737. data/test/results/omopv4_plus/one_in_two_out/crit_icd9 +19 -0
  738. data/test/results/omopv4_plus/one_in_two_out/results_1 +803 -0
  739. data/test/results/omopv4_plus/one_in_two_out/results_2 +803 -0
  740. data/test/results/omopv4_plus/overlapped_by/crit_1 +5 -0
  741. data/test/results/omopv4_plus/overlapped_by/crit_2 +2 -0
  742. data/test/results/omopv4_plus/overlapped_by/crit_3 +5 -0
  743. data/test/results/omopv4_plus/overlapped_by/crit_4 +2 -0
  744. data/test/results/omopv4_plus/overlaps/crit_1 +5 -0
  745. data/test/results/omopv4_plus/overlaps/crit_2 +2 -0
  746. data/test/results/omopv4_plus/overlaps/crit_3 +5 -0
  747. data/test/results/omopv4_plus/overlaps/crit_4 +2 -0
  748. data/test/results/omopv4_plus/person/anno_has_arguments +22 -0
  749. data/test/results/omopv4_plus/person/anno_multiple_upstreams +52 -0
  750. data/test/results/omopv4_plus/person/count_2 +3 -0
  751. data/test/results/omopv4_plus/person/crit_1 +41 -0
  752. data/test/results/omopv4_plus/person_filter/count_1 +4 -0
  753. data/test/results/omopv4_plus/person_filter/crit_1 +52 -0
  754. data/test/results/omopv4_plus/person_filter/crit_2 +10 -0
  755. data/test/results/omopv4_plus/person_filter/crit_3 +32 -0
  756. data/test/results/omopv4_plus/person_filter/crit_4 +50 -0
  757. data/test/results/omopv4_plus/place_of_service_code/anno_has_upstreams +37 -0
  758. data/test/results/omopv4_plus/place_of_service_code/anno_no_arguments +18 -0
  759. data/test/results/omopv4_plus/place_of_service_code/crit_basic +157 -0
  760. data/test/results/omopv4_plus/place_of_service_filter/anno_1 +29 -0
  761. data/test/results/omopv4_plus/procedure_occurrence/anno_has_arguments +37 -0
  762. data/test/results/omopv4_plus/procedure_occurrence/anno_multiple_upstreams +51 -0
  763. data/test/results/omopv4_plus/procedure_occurrence/count_gender +3 -0
  764. data/test/results/omopv4_plus/procedure_occurrence/count_icd9 +3 -0
  765. data/test/results/omopv4_plus/procedure_occurrence/count_started_by +3 -0
  766. data/test/results/omopv4_plus/provenance/anno_1 +29 -0
  767. data/test/results/omopv4_plus/provenance/anno_bad_keyword +38 -0
  768. data/test/results/omopv4_plus/provenance/count_1 +3 -0
  769. data/test/results/omopv4_plus/provenance/count_2 +3 -0
  770. data/test/results/omopv4_plus/provider_filter/anno_1 +29 -0
  771. data/test/results/omopv4_plus/race/anno_1 +37 -0
  772. data/test/results/omopv4_plus/race/anno_2 +18 -0
  773. data/test/results/omopv4_plus/race/crit_1 +32 -0
  774. data/test/results/omopv4_plus/read/anno_1 +15 -0
  775. data/test/results/omopv4_plus/read/crit_1 +2 -0
  776. data/test/results/omopv4_plus/recall/anno_1 +54 -0
  777. data/test/results/omopv4_plus/recall/anno_2 +66 -0
  778. data/test/results/omopv4_plus/recall/anno_3 +20 -0
  779. data/test/results/omopv4_plus/recall/anno_4 +18 -0
  780. data/test/results/omopv4_plus/recall/anno_5 +24 -0
  781. data/test/results/omopv4_plus/recall/anno_6 +270 -0
  782. data/test/results/omopv4_plus/recall/crit_1 +19 -0
  783. data/test/results/omopv4_plus/recall/crit_2 +52 -0
  784. data/test/results/omopv4_plus/recall/crit_3 +2 -0
  785. data/test/results/omopv4_plus/recall/crit_cte_1 +41 -0
  786. data/test/results/omopv4_plus/recall/crit_cte_2 +41 -0
  787. data/test/results/omopv4_plus/recall/crit_nested_perm_0 +52 -0
  788. data/test/results/omopv4_plus/revenue_code/crit_1 +2 -0
  789. data/test/results/omopv4_plus/revenue_code/crit_basic +2 -0
  790. data/test/results/omopv4_plus/revenue_code/domains_1 +3 -0
  791. data/test/results/omopv4_plus/revenue_code/domains_drg100 +3 -0
  792. data/test/results/omopv4_plus/rxnorm/crit_1 +2 -0
  793. data/test/results/omopv4_plus/snomed/crit_1 +2 -0
  794. data/test/results/omopv4_plus/started_by/crit_1 +5 -0
  795. data/test/results/omopv4_plus/started_by/crit_2 +2 -0
  796. data/test/results/omopv4_plus/started_by/crit_3 +2 -0
  797. data/test/results/omopv4_plus/sum/anno_1 +18 -0
  798. data/test/results/omopv4_plus/sum/anno_2 +36 -0
  799. data/test/results/omopv4_plus/sum/num_1 +2 -0
  800. data/test/results/omopv4_plus/sum/num_2 +5 -0
  801. data/test/results/omopv4_plus/sum/num_3 +254 -0
  802. data/test/results/omopv4_plus/time_window/anno_1 +20 -0
  803. data/test/results/omopv4_plus/time_window/anno_2 +40 -0
  804. data/test/results/omopv4_plus/time_window/anno_3 +36 -0
  805. data/test/results/omopv4_plus/time_window/anno_4 +39 -0
  806. data/test/results/omopv4_plus/time_window/anno_5 +57 -0
  807. data/test/results/omopv4_plus/time_window/crit_1 +52 -0
  808. data/test/results/omopv4_plus/time_window/crit_2 +157 -0
  809. data/test/results/omopv4_plus/time_window/crit_3 +52 -0
  810. data/test/results/omopv4_plus/time_window/crit_4 +157 -0
  811. data/test/results/omopv4_plus/trim_date_end/crit_1 +5 -0
  812. data/test/results/omopv4_plus/trim_date_end/crit_2 +2 -0
  813. data/test/results/omopv4_plus/trim_date_end/crit_3 +6 -0
  814. data/test/results/omopv4_plus/trim_date_end/crit_at_least +5 -0
  815. data/test/results/omopv4_plus/trim_date_end/crit_occurrences_1 +2 -0
  816. data/test/results/omopv4_plus/trim_date_end/crit_occurrences_2 +6 -0
  817. data/test/results/omopv4_plus/trim_date_end/crit_within +5 -0
  818. data/test/results/omopv4_plus/trim_date_start/crit_1 +5 -0
  819. data/test/results/omopv4_plus/trim_date_start/crit_2 +2 -0
  820. data/test/results/omopv4_plus/trim_date_start/crit_3 +6 -0
  821. data/test/results/omopv4_plus/trim_date_start/crit_at_least +5 -0
  822. data/test/results/omopv4_plus/trim_date_start/crit_occurrences_1 +2 -0
  823. data/test/results/omopv4_plus/trim_date_start/crit_occurrences_2 +6 -0
  824. data/test/results/omopv4_plus/trim_date_start/crit_within +5 -0
  825. data/test/results/omopv4_plus/union/anno_1 +43 -0
  826. data/test/results/omopv4_plus/union/anno_2 +74 -0
  827. data/test/results/omopv4_plus/union/anno_3 +18 -0
  828. data/test/results/omopv4_plus/union/anno_4 +25 -0
  829. data/test/results/omopv4_plus/union/anno_5 +33 -0
  830. data/test/results/omopv4_plus/union/anno_6 +46 -0
  831. data/test/results/omopv4_plus/union/count_1 +3 -0
  832. data/test/results/omopv4_plus/union/count_2 +3 -0
  833. data/test/results/omopv4_plus/union/count_3 +3 -0
  834. data/test/results/omopv4_plus/union/count_4 +3 -0
  835. data/test/results/omopv4_plus/union/count_5 +4 -0
  836. data/test/results/omopv4_plus/union/optcc_1 +3 -0
  837. data/test/results/omopv4_plus/union/optcc_2 +3 -0
  838. data/test/results/omopv4_plus/union/optcc_3 +3 -0
  839. data/test/results/omopv4_plus/union/optcc_4 +3 -0
  840. data/test/results/omopv4_plus/union/optcc_5 +3 -0
  841. data/test/results/omopv4_plus/union/optcc_6 +3 -0
  842. data/test/results/omopv4_plus/union/scanno_1 +22 -0
  843. data/test/results/omopv4_plus/union/scanno_2 +36 -0
  844. data/test/results/omopv4_plus/visit_occurrence/anno_1 +52 -0
  845. data/test/results/omopv4_plus/visit_occurrence/anno_2 +37 -0
  846. data/test/results/omopv4_plus/visit_occurrence/crit_1 +52 -0
  847. data/test/results/omopv4_plus/visit_occurrence/crit_2 +22945 -0
  848. data/test/results/omopv4_plus/visit_occurrence/crit_3 +46851 -0
  849. data/test/statements/after/anno_1 +7 -0
  850. data/test/statements/after/anno_2 +16 -0
  851. data/test/statements/after/anno_3 +9 -0
  852. data/test/statements/after/anno_4 +19 -0
  853. data/test/statements/after/anno_5 +21 -0
  854. data/test/statements/after/anno_6 +16 -0
  855. data/test/statements/after/crit_at_least +21 -0
  856. data/test/statements/after/crit_basic +20 -0
  857. data/test/statements/after/crit_occurrences +21 -0
  858. data/test/statements/after/crit_within +21 -0
  859. data/test/statements/any_overlap/crit_basic1 +16 -0
  860. data/test/statements/any_overlap/crit_basic2 +16 -0
  861. data/test/statements/any_overlap/crit_occurrences1 +17 -0
  862. data/test/statements/any_overlap/crit_occurrences2 +17 -0
  863. data/test/statements/any_overlap/crit_within +17 -0
  864. data/test/statements/before/crit_at_least +14 -0
  865. data/test/statements/before/crit_basic1 +13 -0
  866. data/test/statements/before/crit_basic2 +16 -0
  867. data/test/statements/before/crit_occurrences +14 -0
  868. data/test/statements/before/crit_within +14 -0
  869. data/test/statements/co_reported/anno_1 +13 -0
  870. data/test/statements/co_reported/anno_2 +21 -0
  871. data/test/statements/co_reported/anno_3 +14 -0
  872. data/test/statements/complement/anno_duplicate_params +11 -0
  873. data/test/statements/complement/anno_invalid_params +8 -0
  874. data/test/statements/complement/anno_no_params +3 -0
  875. data/test/statements/complement/count_3way_intersect +24 -0
  876. data/test/statements/complement/count_3way_union +18 -0
  877. data/test/statements/complement/count_intersect +17 -0
  878. data/test/statements/complement/count_union +14 -0
  879. data/test/statements/complement/count_union_and_intersect +27 -0
  880. data/test/statements/complement/crit_basic1 +7 -0
  881. data/test/statements/complement/crit_icd9_selector +10 -0
  882. data/test/statements/complex/anno_1 +29 -0
  883. data/test/statements/complex/crit_1 +278 -0
  884. data/test/statements/complex/crit_2 +43 -0
  885. data/test/statements/complex/crit_3 +54 -0
  886. data/test/statements/complex/crit_4 +17 -0
  887. data/test/statements/complex/crit_5 +17 -0
  888. data/test/statements/complex/crit_6 +20 -0
  889. data/test/statements/complex/crit_7 +14 -0
  890. data/test/statements/complex/crit_out_of_order_ctes +39 -0
  891. data/test/statements/complex/scanno_1 +1508 -0
  892. data/test/statements/concurrent_within/crit_icd9 +11 -0
  893. data/test/statements/concurrent_within/crit_icd9_and_place_of_service +15 -0
  894. data/test/statements/concurrent_within/crit_negative_start +15 -0
  895. data/test/statements/condition_type/anno_icd9 +7 -0
  896. data/test/statements/condition_type/count_condition_era +4 -0
  897. data/test/statements/condition_type/count_condition_era_30_day_window +4 -0
  898. data/test/statements/condition_type/count_ehr_problem_list +4 -0
  899. data/test/statements/condition_type/count_era_0 +4 -0
  900. data/test/statements/condition_type/count_inpatient +4 -0
  901. data/test/statements/condition_type/count_inpatient_detail +4 -0
  902. data/test/statements/condition_type/count_inpatient_header +4 -0
  903. data/test/statements/condition_type/count_inpatient_header_2 +4 -0
  904. data/test/statements/condition_type/count_inpatient_header_3 +4 -0
  905. data/test/statements/condition_type/count_inpatient_header_4 +4 -0
  906. data/test/statements/condition_type/count_inpatient_header_5 +4 -0
  907. data/test/statements/condition_type/count_inpatient_outpatient_detail +5 -0
  908. data/test/statements/condition_type/count_inpatient_primary +4 -0
  909. data/test/statements/condition_type/count_inpatient_primary_or_first +4 -0
  910. data/test/statements/condition_type/count_outpatient +4 -0
  911. data/test/statements/condition_type/count_outpatient_detail +4 -0
  912. data/test/statements/condition_type/count_outpatient_header +4 -0
  913. data/test/statements/condition_type/count_outpatient_primary +4 -0
  914. data/test/statements/condition_type/count_primary +4 -0
  915. data/test/statements/contains/crit_1 +16 -0
  916. data/test/statements/contains/crit_2 +16 -0
  917. data/test/statements/contains/crit_3 +16 -0
  918. data/test/statements/count/anno_multiple_upstreams +11 -0
  919. data/test/statements/count/anno_no_upstream1 +3 -0
  920. data/test/statements/count/anno_no_upstream2 +4 -0
  921. data/test/statements/count/crit_icd9_ndc +15 -0
  922. data/test/statements/count/crit_ndc +11 -0
  923. data/test/statements/count/crit_person +7 -0
  924. data/test/statements/cpt/anno_icd9_upstream +7 -0
  925. data/test/statements/cpt/anno_invalid_code +5 -0
  926. data/test/statements/cpt/count_1 +4 -0
  927. data/test/statements/cpt/crit_1 +4 -0
  928. data/test/statements/cpt/scanno_1 +4 -0
  929. data/test/statements/cpt_or_hcpcs/anno_bad_format +7 -0
  930. data/test/statements/cpt_or_hcpcs/count_1 +5 -0
  931. data/test/statements/cpt_or_hcpcs/crit_1 +5 -0
  932. data/test/statements/date_range/anno_1 +7 -0
  933. data/test/statements/date_range/anno_extra_argument +8 -0
  934. data/test/statements/date_range/anno_invalid_argument +7 -0
  935. data/test/statements/date_range/anno_missing_argument1 +6 -0
  936. data/test/statements/date_range/anno_missing_argument2 +6 -0
  937. data/test/statements/date_range/anno_no_upstreams +11 -0
  938. data/test/statements/date_range/count_1 +7 -0
  939. data/test/statements/date_range/count_2 +7 -0
  940. data/test/statements/death/anno_multiple_upstreams +10 -0
  941. data/test/statements/death/anno_no_upstreams +4 -0
  942. data/test/statements/death/crit_basic +3 -0
  943. data/test/statements/death/crit_person +7 -0
  944. data/test/statements/drug_type_concept/anno_has_upstreams +8 -0
  945. data/test/statements/drug_type_concept/anno_no_arguments +3 -0
  946. data/test/statements/drug_type_concept/crit_basic1 +4 -0
  947. data/test/statements/drug_type_concept/crit_basic2 +4 -0
  948. data/test/statements/during/crit_1 +16 -0
  949. data/test/statements/during/crit_2 +16 -0
  950. data/test/statements/equal/crit_1 +17 -0
  951. data/test/statements/equal/crit_2 +21 -0
  952. data/test/statements/except/anno_1 +13 -0
  953. data/test/statements/except/anno_2 +14 -0
  954. data/test/statements/except/count_complex +31 -0
  955. data/test/statements/except/crit_412_cpt +13 -0
  956. data/test/statements/except/crit_412_inpatient +13 -0
  957. data/test/statements/filter/crit_1 +15 -0
  958. data/test/statements/first/anno_argument +4 -0
  959. data/test/statements/first/anno_no_upstream +3 -0
  960. data/test/statements/first/crit_cpt +7 -0
  961. data/test/statements/first/crit_icd9 +7 -0
  962. data/test/statements/first/crit_union +14 -0
  963. data/test/statements/from/anno_has_upstreams +7 -0
  964. data/test/statements/from/anno_multiple_arguments +5 -0
  965. data/test/statements/from_seer_visits/anno_multiple_upstreams +17 -0
  966. data/test/statements/from_seer_visits/anno_no_upstream +3 -0
  967. data/test/statements/from_seer_visits/crit_1 +10 -0
  968. data/test/statements/from_seer_visits/crit_2 +11 -0
  969. data/test/statements/from_seer_visits/crit_3 +11 -0
  970. data/test/statements/from_seer_visits/crit_4 +12 -0
  971. data/test/statements/gender/anno_has_upstreams +7 -0
  972. data/test/statements/gender/crit_male +4 -0
  973. data/test/statements/hcpcs/anno_bad_format +6 -0
  974. data/test/statements/hcpcs/crit_A0382 +4 -0
  975. data/test/statements/icd10/anno_bad_format +5 -0
  976. data/test/statements/icd10/anno_has_upstreams +7 -0
  977. data/test/statements/icd10/crit_1 +4 -0
  978. data/test/statements/icd10pcs/anno_bad_format +6 -0
  979. data/test/statements/icd10pcs/anno_has_upstreams +7 -0
  980. data/test/statements/icd10pcs/crit_1 +4 -0
  981. data/test/statements/icd9/anno_empty_label +7 -0
  982. data/test/statements/icd9/anno_invalid_code +4 -0
  983. data/test/statements/icd9/anno_valid_code +4 -0
  984. data/test/statements/icd9/crit_1 +4 -0
  985. data/test/statements/icd9_procedure/crit_1 +4 -0
  986. data/test/statements/intersect/anno_412_inpatient +11 -0
  987. data/test/statements/intersect/anno_has_arguments +4 -0
  988. data/test/statements/intersect/anno_no_upstream +3 -0
  989. data/test/statements/intersect/crit_412_inpatient +11 -0
  990. data/test/statements/intersect/crit_412_male +11 -0
  991. data/test/statements/intersect/crit_complex +19 -0
  992. data/test/statements/invalid/anno_bad_op +13 -0
  993. data/test/statements/invalid/scanno_1 +7 -0
  994. data/test/statements/last/crit_icd9 +7 -0
  995. data/test/statements/loinc/crit_basic +4 -0
  996. data/test/statements/ndc/crit_basic +4 -0
  997. data/test/statements/ndc/results_1 +4 -0
  998. data/test/statements/numeric/anno_multiple_upstreams +11 -0
  999. data/test/statements/numeric/num_values_1 +4 -0
  1000. data/test/statements/numeric/num_values_2 +8 -0
  1001. data/test/statements/numeric/num_values_3 +8 -0
  1002. data/test/statements/observation_period/anno_has_arguments +8 -0
  1003. data/test/statements/observation_period/anno_multiple_upstreams +11 -0
  1004. data/test/statements/observation_period/count_all_periods +4 -0
  1005. data/test/statements/observation_period/crit_female +7 -0
  1006. data/test/statements/observation_period/crit_icd9 +7 -0
  1007. data/test/statements/observation_period/crit_male +7 -0
  1008. data/test/statements/occurrence/anno_no_upstream +3 -0
  1009. data/test/statements/occurrence/count_412_410 +17 -0
  1010. data/test/statements/occurrence/crit_1 +8 -0
  1011. data/test/statements/occurrence/crit_2 +11 -0
  1012. data/test/statements/occurrence/crit_3 +11 -0
  1013. data/test/statements/one_in_two_out/anno_has_arguments +8 -0
  1014. data/test/statements/one_in_two_out/anno_multiple_upstreams +15 -0
  1015. data/test/statements/one_in_two_out/anno_no_upstream +7 -0
  1016. data/test/statements/one_in_two_out/count_1 +10 -0
  1017. data/test/statements/one_in_two_out/count_same_as_1 +11 -0
  1018. data/test/statements/one_in_two_out/crit_hcpcs +10 -0
  1019. data/test/statements/one_in_two_out/crit_icd9 +11 -0
  1020. data/test/statements/one_in_two_out/results_1 +9 -0
  1021. data/test/statements/one_in_two_out/results_2 +9 -0
  1022. data/test/statements/overlapped_by/crit_1 +16 -0
  1023. data/test/statements/overlapped_by/crit_2 +16 -0
  1024. data/test/statements/overlapped_by/crit_3 +16 -0
  1025. data/test/statements/overlapped_by/crit_4 +16 -0
  1026. data/test/statements/overlaps/crit_1 +16 -0
  1027. data/test/statements/overlaps/crit_2 +16 -0
  1028. data/test/statements/overlaps/crit_3 +16 -0
  1029. data/test/statements/overlaps/crit_4 +16 -0
  1030. data/test/statements/person/anno_has_arguments +4 -0
  1031. data/test/statements/person/anno_multiple_upstreams +11 -0
  1032. data/test/statements/person/count_2 +3 -0
  1033. data/test/statements/person/crit_1 +7 -0
  1034. data/test/statements/person_filter/count_1 +20 -0
  1035. data/test/statements/person_filter/crit_1 +20 -0
  1036. data/test/statements/person_filter/crit_2 +13 -0
  1037. data/test/statements/person_filter/crit_3 +13 -0
  1038. data/test/statements/person_filter/crit_4 +13 -0
  1039. data/test/statements/place_of_service_code/anno_has_upstreams +8 -0
  1040. data/test/statements/place_of_service_code/anno_no_arguments +3 -0
  1041. data/test/statements/place_of_service_code/crit_basic +4 -0
  1042. data/test/statements/place_of_service_filter/anno_1 +8 -0
  1043. data/test/statements/procedure_occurrence/anno_has_arguments +8 -0
  1044. data/test/statements/procedure_occurrence/anno_multiple_upstreams +11 -0
  1045. data/test/statements/procedure_occurrence/count_gender +7 -0
  1046. data/test/statements/procedure_occurrence/count_icd9 +7 -0
  1047. data/test/statements/procedure_occurrence/count_started_by +19 -0
  1048. data/test/statements/provenance/anno_1 +8 -0
  1049. data/test/statements/provenance/anno_bad_keyword +10 -0
  1050. data/test/statements/provenance/count_1 +8 -0
  1051. data/test/statements/provenance/count_2 +8 -0
  1052. data/test/statements/provider_filter/anno_1 +10 -0
  1053. data/test/statements/race/anno_1 +8 -0
  1054. data/test/statements/race/anno_2 +3 -0
  1055. data/test/statements/race/crit_1 +4 -0
  1056. data/test/statements/read/anno_1 +4 -0
  1057. data/test/statements/read/crit_1 +8 -0
  1058. data/test/statements/recall/anno_1 +16 -0
  1059. data/test/statements/recall/anno_2 +18 -0
  1060. data/test/statements/recall/anno_3 +4 -0
  1061. data/test/statements/recall/anno_4 +3 -0
  1062. data/test/statements/recall/anno_5 +5 -0
  1063. data/test/statements/recall/anno_6 +107 -0
  1064. data/test/statements/recall/crit_1 +17 -0
  1065. data/test/statements/recall/crit_2 +14 -0
  1066. data/test/statements/recall/crit_3 +16 -0
  1067. data/test/statements/recall/crit_cte_1 +17 -0
  1068. data/test/statements/recall/crit_cte_2 +17 -0
  1069. data/test/statements/recall/crit_nested_perm_0 +28 -0
  1070. data/test/statements/revenue_code/crit_1 +4 -0
  1071. data/test/statements/revenue_code/crit_basic +4 -0
  1072. data/test/statements/revenue_code/domains_1 +4 -0
  1073. data/test/statements/revenue_code/domains_drg100 +4 -0
  1074. data/test/statements/rxnorm/crit_1 +4 -0
  1075. data/test/statements/snomed/crit_1 +4 -0
  1076. data/test/statements/started_by/crit_1 +16 -0
  1077. data/test/statements/started_by/crit_2 +16 -0
  1078. data/test/statements/started_by/crit_3 +16 -0
  1079. data/test/statements/sum/anno_1 +3 -0
  1080. data/test/statements/sum/anno_2 +8 -0
  1081. data/test/statements/sum/num_1 +11 -0
  1082. data/test/statements/sum/num_2 +15 -0
  1083. data/test/statements/sum/num_3 +7 -0
  1084. data/test/statements/time_window/anno_1 +7 -0
  1085. data/test/statements/time_window/anno_2 +11 -0
  1086. data/test/statements/time_window/anno_3 +11 -0
  1087. data/test/statements/time_window/anno_4 +12 -0
  1088. data/test/statements/time_window/anno_5 +15 -0
  1089. data/test/statements/time_window/crit_1 +11 -0
  1090. data/test/statements/time_window/crit_2 +11 -0
  1091. data/test/statements/time_window/crit_3 +11 -0
  1092. data/test/statements/time_window/crit_4 +11 -0
  1093. data/test/statements/trim_date_end/crit_1 +16 -0
  1094. data/test/statements/trim_date_end/crit_2 +16 -0
  1095. data/test/statements/trim_date_end/crit_3 +16 -0
  1096. data/test/statements/trim_date_end/crit_at_least +17 -0
  1097. data/test/statements/trim_date_end/crit_occurrences_1 +17 -0
  1098. data/test/statements/trim_date_end/crit_occurrences_2 +17 -0
  1099. data/test/statements/trim_date_end/crit_within +17 -0
  1100. data/test/statements/trim_date_start/crit_1 +16 -0
  1101. data/test/statements/trim_date_start/crit_2 +16 -0
  1102. data/test/statements/trim_date_start/crit_3 +16 -0
  1103. data/test/statements/trim_date_start/crit_at_least +17 -0
  1104. data/test/statements/trim_date_start/crit_occurrences_1 +17 -0
  1105. data/test/statements/trim_date_start/crit_occurrences_2 +17 -0
  1106. data/test/statements/trim_date_start/crit_within +17 -0
  1107. data/test/statements/union/anno_1 +11 -0
  1108. data/test/statements/union/anno_2 +18 -0
  1109. data/test/statements/union/anno_3 +3 -0
  1110. data/test/statements/union/anno_4 +4 -0
  1111. data/test/statements/union/anno_5 +7 -0
  1112. data/test/statements/union/anno_6 +10 -0
  1113. data/test/statements/union/count_1 +11 -0
  1114. data/test/statements/union/count_2 +11 -0
  1115. data/test/statements/union/count_3 +15 -0
  1116. data/test/statements/union/count_4 +18 -0
  1117. data/test/statements/union/count_5 +18 -0
  1118. data/test/statements/union/scanno_1 +3 -0
  1119. data/test/statements/union/scanno_2 +18 -0
  1120. data/test/statements/visit_occurrence/anno_1 +11 -0
  1121. data/test/statements/visit_occurrence/anno_2 +8 -0
  1122. data/test/statements/visit_occurrence/crit_1 +7 -0
  1123. data/test/statements/visit_occurrence/crit_2 +7 -0
  1124. data/test/statements/visit_occurrence/crit_3 +3 -0
  1125. metadata +2016 -150
  1126. data/lib/conceptql/behaviors/debuggable.rb +0 -70
  1127. data/lib/conceptql/behaviors/dottable.rb +0 -103
  1128. data/lib/conceptql/behaviors/preppable.rb +0 -20
  1129. data/lib/conceptql/converter.rb +0 -65
  1130. data/lib/conceptql/debugger.rb +0 -48
  1131. data/lib/conceptql/fake_grapher.rb +0 -20
  1132. data/lib/conceptql/graph.rb +0 -52
  1133. data/lib/conceptql/graph_nodifier.rb +0 -203
  1134. data/lib/conceptql/operators/concept.rb +0 -70
  1135. data/lib/conceptql/operators/snomed_condition.rb +0 -26
  1136. data/lib/conceptql/operators/visit.rb +0 -15
  1137. data/lib/conceptql/tree.rb +0 -53
  1138. data/lib/conceptql/utils/temp_table.rb +0 -72
  1139. data/spec/conceptql/behaviors/dottable_spec.rb +0 -99
  1140. data/spec/conceptql/converter_spec.rb +0 -51
  1141. data/spec/conceptql/date_adjuster_spec.rb +0 -68
  1142. data/spec/conceptql/operators/after_spec.rb +0 -16
  1143. data/spec/conceptql/operators/before_spec.rb +0 -16
  1144. data/spec/conceptql/operators/casting_operator_spec.rb +0 -68
  1145. data/spec/conceptql/operators/complement_spec.rb +0 -15
  1146. data/spec/conceptql/operators/concept_spec.rb +0 -40
  1147. data/spec/conceptql/operators/condition_type_spec.rb +0 -128
  1148. data/spec/conceptql/operators/contains_spec.rb +0 -19
  1149. data/spec/conceptql/operators/cpt_spec.rb +0 -29
  1150. data/spec/conceptql/operators/date_range_spec.rb +0 -33
  1151. data/spec/conceptql/operators/death_spec.rb +0 -10
  1152. data/spec/conceptql/operators/during_spec.rb +0 -30
  1153. data/spec/conceptql/operators/except_spec.rb +0 -15
  1154. data/spec/conceptql/operators/first_spec.rb +0 -35
  1155. data/spec/conceptql/operators/from_spec.rb +0 -13
  1156. data/spec/conceptql/operators/gender_spec.rb +0 -27
  1157. data/spec/conceptql/operators/hcpcs_spec.rb +0 -29
  1158. data/spec/conceptql/operators/icd10_spec.rb +0 -34
  1159. data/spec/conceptql/operators/icd9_procedure_spec.rb +0 -29
  1160. data/spec/conceptql/operators/icd9_spec.rb +0 -34
  1161. data/spec/conceptql/operators/intersect_spec.rb +0 -28
  1162. data/spec/conceptql/operators/last_spec.rb +0 -36
  1163. data/spec/conceptql/operators/loinc_spec.rb +0 -29
  1164. data/spec/conceptql/operators/medcode_procedure_spec.rb +0 -34
  1165. data/spec/conceptql/operators/medcode_spec.rb +0 -34
  1166. data/spec/conceptql/operators/observation_period_spec.rb +0 -10
  1167. data/spec/conceptql/operators/occurrence_spec.rb +0 -87
  1168. data/spec/conceptql/operators/overlapped_by_spec.rb +0 -32
  1169. data/spec/conceptql/operators/overlaps_spec.rb +0 -21
  1170. data/spec/conceptql/operators/person_filter_spec.rb +0 -15
  1171. data/spec/conceptql/operators/person_spec.rb +0 -10
  1172. data/spec/conceptql/operators/place_of_service_code_spec.rb +0 -24
  1173. data/spec/conceptql/operators/procedure_occurrence_spec.rb +0 -10
  1174. data/spec/conceptql/operators/prodcode_spec.rb +0 -35
  1175. data/spec/conceptql/operators/query_double.rb +0 -20
  1176. data/spec/conceptql/operators/query_double_spec.rb +0 -7
  1177. data/spec/conceptql/operators/race_spec.rb +0 -21
  1178. data/spec/conceptql/operators/rxnorm_spec.rb +0 -29
  1179. data/spec/conceptql/operators/snomed_spec.rb +0 -29
  1180. data/spec/conceptql/operators/source_vocabulary_operator_spec.rb +0 -35
  1181. data/spec/conceptql/operators/standard_vocabulary_operator_spec.rb +0 -35
  1182. data/spec/conceptql/operators/started_by_spec.rb +0 -22
  1183. data/spec/conceptql/operators/temporal_operator_spec.rb +0 -51
  1184. data/spec/conceptql/operators/time_window_spec.rb +0 -77
  1185. data/spec/conceptql/operators/union_spec.rb +0 -21
  1186. data/spec/conceptql/operators/visit_occurrence_spec.rb +0 -10
  1187. data/spec/conceptql/query_spec.rb +0 -22
  1188. data/spec/conceptql/tree_spec.rb +0 -50
  1189. data/spec/doubles/stream_for_casting_double.rb +0 -9
  1190. data/spec/doubles/stream_for_occurrence_double.rb +0 -25
  1191. data/spec/doubles/stream_for_temporal_double.rb +0 -6
  1192. data/spec/spec_helper.rb +0 -102
@@ -12,12 +12,14 @@ module ConceptQL
12
12
  # - Either a number value or a symbol representing a column name
13
13
  # - An optional stream
14
14
  class Numeric < PassThru
15
+ register __FILE__
16
+
15
17
  desc <<-EOF
16
- Represents a operator that will either:
17
- - create a value_as_number value for every person in the database
18
- - change the value_as_number value for every every result passed in
19
- - either to a number
20
- - or a value from a column in the origin row
18
+ Represents an operator that will either:
19
+ - Create a value_as_number value for every person in the database
20
+ - Change the value_as_number value for every result passed in
21
+ - Either to a number
22
+ - Or a value from a column in the origin row
21
23
 
22
24
  Accepts two params:
23
25
  - Either a number value or a symbol representing a column name
@@ -25,29 +27,46 @@ Accepts two params:
25
27
  EOF
26
28
  argument :value, type: :float
27
29
  allows_one_upstream
30
+ validate_at_most_one_upstream
31
+ validate_one_argument
32
+ default_query_columns
33
+ require_column :value_as_number
34
+
35
+ def query_cols
36
+ dynamic_columns - [:value_as_number] + [:value_as_number]
37
+ end
28
38
 
29
39
  def query(db)
30
40
  stream.nil? ? as_criterion(db) : with_kids(db)
31
41
  end
32
42
 
33
- def types
43
+ def domains(db)
34
44
  stream.nil? ? [:person] : super
35
45
  end
36
46
 
37
47
  private
38
48
  def with_kids(db)
39
49
  db.from(stream.evaluate(db))
40
- .select(*(COLUMNS - [:value_as_number]))
41
- .select_append(Sequel.lit('?', arguments.first).cast(Float).as(:value_as_number))
50
+ .select(*(dynamic_columns - [:value_as_number]))
51
+ .select_append(first_argument.cast(Float).as(:value_as_number))
42
52
  .from_self
43
53
  end
44
54
 
45
55
  def as_criterion(db)
46
- db.from(select_it(db.from(:person), :person))
47
- .select(*(COLUMNS - [:value_as_number]))
48
- .select_append(Sequel.lit('?', arguments.first).cast(Float).as(:value_as_number))
56
+ db.from(select_it(db.from(:person).clone(:force_columns=>table_columns(:person)), :person))
57
+ .select(*(dynamic_columns - [:value_as_number]))
58
+ .select_append(first_argument.cast(Float).as(:value_as_number))
49
59
  .from_self
50
60
  end
61
+
62
+ def first_argument
63
+ case arguments.first
64
+ when String
65
+ Sequel.identifier(arguments.first)
66
+ else
67
+ Sequel.expr(arguments.first)
68
+ end
69
+ end
51
70
  end
52
71
  end
53
72
  end
@@ -1,11 +1,14 @@
1
1
  require_relative 'source_vocabulary_operator'
2
+ require_relative '../behaviors/labish'
2
3
 
3
4
  module ConceptQL
4
5
  module Operators
5
6
  class ObservationByEnttype < SourceVocabularyOperator
6
- desc 'Searches the observation table for all observations with matching Enttype'
7
+ register __FILE__
8
+
7
9
  argument :enttypes, type: :codelist, vocab_id: [206, 207]
8
- predominant_types :observation
10
+ predominant_domains :observation
11
+ include ConceptQL::Labish
9
12
 
10
13
  def table
11
14
  :observation
@@ -3,11 +3,13 @@ require_relative 'casting_operator'
3
3
  module ConceptQL
4
4
  module Operators
5
5
  class ObservationPeriod < CastingOperator
6
+ register __FILE__
7
+
6
8
  desc 'Generates all observation_period records, or, if fed a stream, fetches all observation_period records for the people represented in the incoming result set.'
7
- types :observation_period
9
+ domains :observation_period
8
10
  allows_one_upstream
9
11
 
10
- def my_type
12
+ def my_domain
11
13
  :observation_period
12
14
  end
13
15
 
@@ -16,12 +18,12 @@ module ConceptQL
16
18
  end
17
19
 
18
20
  def these_point_at_me
19
- # I could list ALL the types we use, but the default behavior of casting,
21
+ # I could list ALL the domains we use, but the default behavior of casting,
20
22
  # when there is no explicit casting defined, is to convert everything to
21
23
  # person IDs
22
24
  #
23
25
  # So by defining no known castable relationships in this operator, all
24
- # types will be converted to person
26
+ # domains will be converted to person
25
27
  []
26
28
  end
27
29
  end
@@ -22,32 +22,39 @@ module ConceptQL
22
22
  # If we ask for the second occurrence of something and a person has only one
23
23
  # occurrence, this operator returns nothing for that person
24
24
  class Occurrence < Operator
25
+ register __FILE__
26
+
25
27
  preferred_name 'Nth Occurrence'
28
+
26
29
  desc <<-EOF
27
- Groups all results by person, then orders by start_date, then finds the nth occurrence.
28
- nth occurrence can be positive or negative.
30
+ Groups all results by person, then orders by start_date and finds the nth occurrence (can be positive or negative).
29
31
  1 => first
30
32
  2 => second
31
33
  ...
32
34
  -1 => last
33
35
  -2 => second-to-last
34
36
 
35
- If two rows have the same start_date, the order of their ranking
36
- is arbitrary
37
+ If two results have the same start_date, their relative order
38
+ is arbitrary.
37
39
 
38
40
  If we ask for the second occurrence of something and a person has only one
39
- occurrence, this operator returns nothing for that person
41
+ occurrence, this operator returns nothing for that person.
40
42
  EOF
43
+
41
44
  argument :occurrence, type: :integer
45
+ category "Filter Single Stream"
46
+ basic_type :temporal
42
47
  allows_one_upstream
43
- category %w(Temporal Occurrence)
48
+ validate_at_least_one_upstream
49
+ option :unique, type: :boolean, label: 'Unique Source Values Only'
50
+
51
+ def query_cols
52
+ dynamic_columns + [:rn]
53
+ end
44
54
 
45
55
  def query(db)
46
56
  db[:occurrences]
47
- .with(:occurrences,
48
- stream.evaluate(db)
49
- .from_self
50
- .select_append { |o| o.row_number(:over, partition: :person_id, order: ordered_columns){}.as(:rn) })
57
+ .with(:occurrences, occurrences(db))
51
58
  .where(rn: occurrence.abs)
52
59
  end
53
60
 
@@ -55,14 +62,43 @@ occurrence, this operator returns nothing for that person
55
62
  @occurrence ||= arguments.first
56
63
  end
57
64
 
65
+ def occurrences(db)
66
+ all_or_uniquified_results(db)
67
+ .from_self
68
+ .select_append { |o| o.row_number(:over, partition: :person_id, order: ordered_columns){}.as(:rn) }
69
+ end
70
+
58
71
  private
72
+
73
+ def validate(db, opts = {})
74
+ super
75
+ if self.class == Occurrence
76
+ validate_one_argument
77
+ else
78
+ validate_no_arguments
79
+ end
80
+ end
81
+
59
82
  def asc_or_desc
60
83
  occurrence < 0 ? :desc : :asc
61
84
  end
62
85
 
63
86
  def ordered_columns
64
87
  ordered_columns = [Sequel.send(asc_or_desc, :start_date)]
65
- ordered_columns += [:criterion_type, :criterion_id]
88
+ ordered_columns += [:criterion_id]
89
+ end
90
+
91
+ def uniquify_partition_columns
92
+ dynamic_columns - [:criterion_id, :start_date, :end_date]
93
+ end
94
+
95
+ def all_or_uniquified_results(db)
96
+ return stream.evaluate(db) unless options[:unique]
97
+ stream.evaluate(db)
98
+ .from_self
99
+ .select_append { |o| o.row_number(:over, partition: uniquify_partition_columns, order: ordered_columns){}.as(:unique_rn) }
100
+ .from_self
101
+ .where(unique_rn: 1)
66
102
  end
67
103
  end
68
104
  end
@@ -1,60 +1,123 @@
1
1
  require_relative 'operator'
2
2
  require_relative 'visit_occurrence'
3
+ require_relative '../date_adjuster'
4
+ require_relative '../behaviors/provenanceable'
5
+ require 'facets/kernel/blank'
3
6
 
4
7
  module ConceptQL
5
8
  module Operators
6
9
  class OneInTwoOut < Operator
10
+ register __FILE__
11
+
12
+ include ConceptQL::Provenanceable
13
+
7
14
  desc <<-EOF
8
- Represents a common pattern in research algorithms: searching for a condition
9
- that appears either two times in an outpatient setting with a 30-day gap or once
10
- in an inpatient setting
15
+ Represents a common pattern in research algorithms: searching for an event
16
+ that appears either once in an inpatient setting or
17
+ twice in an outpatient setting with a 30-day gap.
11
18
  EOF
12
19
  allows_one_upstream
13
- category %w(Temporal Relative)
20
+ validate_one_upstream
21
+ validate_no_arguments
22
+ category "Filter Single Stream"
23
+ basic_type :temporal
14
24
 
15
- def types
16
- [:visit_occurrence]
17
- end
25
+ option :inpatient_length_of_stay, type: :integer, min: 0, default: 0, desc: 'Minimum length of inpatient stay (in days) required for inpatient event to be valid', label: 'Inpatient Length of Stay (Days)'
26
+ option :inpatient_return_date, type: :string, options: ['Admit Date', 'Discharge Date'], default: 'Discharge Date', desc: 'Which date to pass downstream in both the start_date and end_date fields'
27
+ option :outpatient_minimum_gap, type: :string, default: '30d', desc: 'Minimum number of days between outpatient events for the event to be valid'
28
+ option :outpatient_maximum_gap, type: :string, desc: 'Maximum number of days between outpatient events for the event to be valid'
29
+ option :outpatient_event_to_return, type: :string, options: ['Initial Event', 'Confirming Event'], default: 'Initial Event', desc: 'Which event to pass downstream'
30
+
31
+ validate_option DateAdjuster::VALID_INPUT, :outpatient_minimum_gap, :outpatient_maximum_gap
32
+
33
+ default_query_columns
34
+
35
+ require_column :provenance_type
36
+
37
+ attr_reader :db
18
38
 
19
39
  def query(db)
20
- inpatient = select_it(visit_query(db).where(place_of_service_concept_id: 8717), :visit_occurrence).from_self
21
- outpatient = select_it(visit_query(db).exclude(place_of_service_concept_id: 8717), :visit_occurrence).from_self
22
-
23
- gap = options[:gap] || 30
24
- valid_outpatient_people = outpatient
25
- .group_by(:person_id)
26
- .select(:person_id)
27
- .select_append(Sequel.expr(Sequel.function(:max, :start_date) - Sequel.function(:min, :end_date)).as(:date_diff))
40
+ @db = db
41
+ first_valid_event.from_self
42
+ end
43
+
44
+ private
45
+
46
+ def condition_events
47
+ db[stream.evaluate(db)]
48
+ .where(criterion_domain: 'condition_occurrence')
49
+ .exclude(provenance_type: nil)
28
50
  .from_self
29
- .where{ date_diff >= gap}
51
+ end
30
52
 
31
- relevant_outpatient = outpatient.where(person_id: valid_outpatient_people.select(:person_id))
32
- earliest(db, inpatient.union(relevant_outpatient))
53
+ def all_inpatient_events
54
+ condition_events
55
+ .where(provenance_type: to_concept_id(:inpatient))
56
+ .from_self
33
57
  end
34
58
 
35
- private
36
- def visit_query(db)
37
- VisitOccurrence.new(FakeOperator.new(stream.evaluate(db).from_self, stream.types)).query(db)
59
+ def valid_inpatient_events
60
+ q = all_inpatient_events
61
+ unless options[:inpatient_length_of_stay].nil? || options[:inpatient_length_of_stay].to_i.zero?
62
+ q = q.where{ |o| Sequel.date_sub(o.end_date, o.start_date) > options[:inpatient_length_of_stay].to_i }
63
+ end
64
+
65
+ if options[:inpatient_return_date] != 'Admit Date'
66
+ q = q.select(*(query_cols - [:start_date])).select_append(:end_date___start_date)
67
+ end
68
+
69
+ q.from_self.select(*dynamic_columns).from_self
38
70
  end
39
71
 
40
- def earliest(db, query)
41
- db[:earliest]
42
- .with(:earliest,
43
- query.select_append { |o| o.row_number(:over, partition: :person_id, order: [Sequel.asc(:start_date), :criterion_type, :criterion_id]){}.as(:rn) })
44
- .where(rn: 1)
72
+ def outpatient_events
73
+ condition_events
74
+ .where(provenance_type: to_concept_id(:claim) + to_concept_id(:outpatient))
45
75
  .from_self
46
76
  end
47
77
 
48
- class FakeOperator < Operator
49
- attr :types
50
- def initialize(query, types)
51
- @query = query
52
- @types = types
78
+ def valid_outpatient_events
79
+
80
+ min_gap = options[:outpatient_minimum_gap] || "30d"
81
+
82
+ max_gap = options[:outpatient_maximum_gap]
83
+
84
+ q = outpatient_events.from_self(alias: :initial)
85
+ .join(outpatient_events.as(:confirm), initial__person_id: :confirm__person_id)
86
+ .exclude(initial__criterion_id: :confirm__criterion_id)
87
+
88
+ # In order to avoid many more comparisons of initial to confirm events, we now
89
+ # filter the join by having only confirm events that come on or after initial events
90
+ #
91
+ # This ensures that initial events represent initial events and confirm events
92
+ # represent confirming events
93
+ q = q.exclude{confirm__start_date < initial__start_date}
94
+
95
+ if min_gap.present?
96
+ q = q.where { confirm__start_date >= DateAdjuster.new(min_gap).adjust(:initial__start_date) }
97
+ end
98
+
99
+ if max_gap.present?
100
+ q = q.where { confirm__start_date <= DateAdjuster.new(max_gap).adjust(:initial__start_date) }
53
101
  end
54
102
 
55
- def query(db)
56
- @query
103
+ if options[:outpatient_event_to_return] != 'Initial Event'
104
+ q = q.select_all(:confirm)
105
+ else
106
+ q = q.select_all(:initial)
57
107
  end
108
+
109
+ q.from_self
110
+ end
111
+
112
+ def all_valid_events
113
+ valid_inpatient_events.union(valid_outpatient_events, all: true)
114
+ end
115
+
116
+ def first_valid_event
117
+ all_valid_events
118
+ .select_append { |o| o.row_number(:over, partition: :person_id, order: [ :start_date, :criterion_id ]){}.as(:rn) }
119
+ .from_self
120
+ .where(rn: 1)
58
121
  end
59
122
  end
60
123
  end
@@ -3,46 +3,246 @@ require_relative '../behaviors/metadatable'
3
3
  require 'facets/array/extract_options'
4
4
  require 'facets/hash/deep_rekey'
5
5
  require 'forwardable'
6
+ require_relative '../query_modifiers/pos_query_modifier'
7
+ require_relative '../query_modifiers/drug_query_modifier'
6
8
 
7
9
  module ConceptQL
8
10
  module Operators
11
+ OPERATORS = {:omopv4=>{}, :omopv4_plus=>{}}.freeze
12
+
13
+ TABLE_VOCABULARY_ID_COLUMN = {
14
+ :condition_occurrence=> :condition_source_vocabulary_id,
15
+ :death=> :cause_of_death_source_vocabulary_id,
16
+ :drug_exposure=> :drug_source_vocabulary_id,
17
+ :observation=> :observation_source_vocabulary_id,
18
+ :procedure_occurrence=> :procedure_source_vocabulary_id,
19
+ :provider=> :specialty_source_vocabulary_id,
20
+ :visit_occurrence=> :place_of_service_source_vocabulary_id
21
+ }.freeze.each_value(&:freeze)
22
+
23
+ TABLE_SOURCE_VALUE_COLUMN = {
24
+ :condition_occurrence=> :condition_source_value,
25
+ :death=> :cause_of_death_source_value,
26
+ :drug_exposure=> :drug_source_value,
27
+ :observation=> :observation_source_value,
28
+ :procedure_occurrence=> :procedure_source_value,
29
+ :provider=> :provider_source_value,
30
+ :visit_occurrence=> :place_of_service_source_value
31
+ }.freeze.each_value(&:freeze)
32
+
33
+ TABLE_COLUMNS = {
34
+ :care_site=>[:care_site_id, :location_id, :organization_id, :place_of_service_concept_id, :care_site_source_value, :place_of_service_source_value],
35
+ :cohort=>[:cohort_id, :cohort_concept_id, :cohort_start_date, :cohort_end_date, :subject_id, :stop_reason],
36
+ :concept=>[:concept_id, :concept_name, :concept_level, :concept_class, :vocabulary_id, :concept_code, :valid_start_date, :valid_end_date, :invalid_reason],
37
+ :concept_ancestor=>[:ancestor_concept_id, :descendant_concept_id, :min_levels_of_separation, :max_levels_of_separation],
38
+ :concept_relationship=>[:concept_id_1, :concept_id_2, :relationship_id, :valid_start_date, :valid_end_date, :invalid_reason],
39
+ :concept_synonym=>[:concept_synonym_id, :concept_id, :concept_synonym_name],
40
+ :condition_era=>[:condition_era_id, :person_id, :condition_concept_id, :condition_era_start_date, :condition_era_end_date, :condition_type_concept_id, :condition_occurrence_count],
41
+ :condition_occurrence=>[:condition_occurrence_id, :person_id, :condition_concept_id, :condition_start_date, :condition_end_date, :condition_type_concept_id, :stop_reason, :associated_provider_id, :visit_occurrence_id, :condition_source_value],
42
+ :death=>[:person_id, :death_date, :death_type_concept_id, :cause_of_death_concept_id, :cause_of_death_source_value],
43
+ :drug_approval=>[:ingredient_concept_id, :approval_date, :approved_by],
44
+ :drug_cost=>[:drug_cost_id, :drug_exposure_id, :paid_copay, :paid_coinsurance, :paid_toward_deductible, :paid_by_payer, :paid_by_coordination_benefits, :total_out_of_pocket, :total_paid, :ingredient_cost, :dispensing_fee, :average_wholesale_price, :payer_plan_period_id],
45
+ :drug_era=>[:drug_era_id, :person_id, :drug_concept_id, :drug_era_start_date, :drug_era_end_date, :drug_type_concept_id, :drug_exposure_count],
46
+ :drug_exposure=>[:drug_exposure_id, :person_id, :drug_concept_id, :drug_exposure_start_date, :drug_exposure_end_date, :drug_type_concept_id, :stop_reason, :refills, :quantity, :days_supply, :sig, :prescribing_provider_id, :visit_occurrence_id, :relevant_condition_concept_id, :drug_source_value],
47
+ :drug_strength=>[:drug_concept_id, :ingredient_concept_id, :amount_value, :amount_unit, :concentration_value, :concentration_enum_unit, :concentration_denom_unit, :valid_start_date, :valid_end_date, :invalid_reason],
48
+ :location=>[:location_id, :address_1, :address_2, :city, :state, :zip, :county, :location_source_value],
49
+ :observation=>[:observation_id, :person_id, :observation_concept_id, :observation_date, :observation_time, :value_as_number, :value_as_string, :value_as_concept_id, :unit_concept_id, :range_low, :range_high, :observation_type_concept_id, :associated_provider_id, :visit_occurrence_id, :relevant_condition_concept_id, :observation_source_value, :unit_source_value],
50
+ :observation_period=>[:observation_period_id, :person_id, :observation_period_start_date, :observation_period_end_date, :prev_ds_period_end_date],
51
+ :organization=>[:organization_id, :place_of_service_concept_id, :location_id, :organization_source_value, :place_of_service_source_value],
52
+ :payer_plan_period=>[:payer_plan_period_id, :person_id, :payer_plan_period_start_date, :payer_plan_period_end_date, :payer_source_value, :plan_source_value, :family_source_value, :prev_ds_period_end_date],
53
+ :person=>[:person_id, :gender_concept_id, :year_of_birth, :month_of_birth, :day_of_birth, :race_concept_id, :ethnicity_concept_id, :location_id, :provider_id, :care_site_id, :person_source_value, :gender_source_value, :race_source_value, :ethnicity_source_value],
54
+ :procedure_cost=>[:procedure_cost_id, :procedure_occurrence_id, :paid_copay, :paid_coinsurance, :paid_toward_deductible, :paid_by_payer, :paid_by_coordination_benefits, :total_out_of_pocket, :total_paid, :disease_class_concept_id, :revenue_code_concept_id, :payer_plan_period_id, :disease_class_source_value, :revenue_code_source_value],
55
+ :procedure_occurrence=>[:procedure_occurrence_id, :person_id, :procedure_concept_id, :procedure_date, :procedure_type_concept_id, :associated_provider_id, :visit_occurrence_id, :relevant_condition_concept_id, :procedure_source_value],
56
+ :provider=>[:provider_id, :npi, :dea, :specialty_concept_id, :care_site_id, :provider_source_value, :specialty_source_value],
57
+ :relationship=>[:relationship_id, :relationship_name, :is_hierarchical, :defines_ancestry, :reverse_relationship],
58
+ :source_to_concept_map=>[:source_code, :source_vocabulary_id, :source_code_description, :target_concept_id, :target_vocabulary_id, :mapping_type, :primary_map, :valid_start_date, :valid_end_date, :invalid_reason],
59
+ :visit_occurrence=>[:visit_occurrence_id, :person_id, :visit_start_date, :visit_end_date, :place_of_service_concept_id, :care_site_id, :place_of_service_source_value],
60
+ :vocabulary=>[:vocabulary_id, :vocabulary_name],
61
+
62
+ # Modifier Tables
63
+ :drug_appendix=>[:drug_name, :drug_amount, :drug_amount_units]
64
+ }.freeze.each_value(&:freeze)
65
+
66
+ def self.operators
67
+ OPERATORS
68
+ end
69
+
9
70
  class Operator
10
71
  extend Forwardable
11
- extend Metadatable
12
- COLUMNS = [
13
- :person_id,
14
- :criterion_id,
15
- :criterion_type,
16
- :start_date,
17
- :end_date,
18
- :value_as_number,
19
- :value_as_string,
20
- :value_as_concept_id,
21
- :units_source_value,
22
- :source_value
23
- ]
24
-
25
- attr :values, :options, :arguments, :upstreams
72
+ extend ConceptQL::Metadatable
73
+
74
+ attr :nodifier, :values, :options, :arguments, :upstreams
26
75
 
27
76
  option :label, type: :string
28
77
 
29
- def initialize(*args)
30
- set_values(*args)
31
- end
78
+ @validations = []
32
79
 
33
- def values=(*args)
34
- set_values(*args)
80
+ class << self
81
+ attr :validations, :codes_regexp, :required_columns
82
+
83
+ def register(file, *data_models)
84
+ data_models = OPERATORS.keys if data_models.empty?
85
+ data_models.each do |dm|
86
+ OPERATORS[dm][File.basename(file).sub(/\.rb\z/, '')] = self
87
+ end
88
+ end
89
+
90
+ def query_columns(*tables)
91
+ define_method(:query_cols) do
92
+ table_columns(*tables)
93
+ end
94
+ end
95
+
96
+ def default_query_columns
97
+ define_method(:query_cols) do
98
+ dynamic_columns
99
+ end
100
+ end
101
+
102
+ def require_column(column)
103
+ @required_columns ||= []
104
+ @required_columns << column
105
+ end
106
+
107
+ validation_meths = (<<-END).split.map(&:to_sym)
108
+ no_upstreams
109
+ one_upstream
110
+ at_least_one_upstream
111
+ at_most_one_upstream
112
+ no_arguments
113
+ one_argument
114
+ at_least_one_argument
115
+ at_most_one_argument
116
+ option
117
+ required_options
118
+ codes_match
119
+ END
120
+
121
+ validation_meths.each do |type|
122
+ meth = :"validate_#{type}"
123
+ define_method(meth) do |*args|
124
+ validations << [meth, *args]
125
+ end
126
+ end
127
+
128
+ def codes_should_match(format)
129
+ @codes_regexp = format
130
+ validate_codes_match
131
+ end
132
+
133
+ def inherited(subclass)
134
+ super
135
+ subclass.instance_variable_set(:@validations, validations.dup)
136
+ subclass.instance_variable_set(:@codes_regexp, codes_regexp.dup) if codes_regexp
137
+ end
138
+
139
+ def new(*)
140
+ operator = super
141
+
142
+ # If operator has a label, replace it with a recall so all references
143
+ # to it use the same code.
144
+ if operator.label && !operator.errors
145
+ operator.scope.add_operator(operator)
146
+ operator = Operators::Recall.new(operator.nodifier, operator.label, replaced: true)
147
+ end
148
+
149
+ operator
150
+ end
35
151
  end
36
152
 
37
- def set_values(*args)
38
- @options = args.extract_options!.deep_rekey
39
- @upstreams, @arguments = args.partition { |arg| arg.is_a?(Operator) }
153
+ def initialize(nodifier, *args)
154
+ @nodifier = nodifier
155
+ @options = {}
156
+ while args.last.is_a?(Hash)
157
+ @options = @options.merge(args.extract_options!.deep_rekey)
158
+ end
159
+ args.reject!{|arg| arg.nil? || arg == ''}
160
+ @upstreams, @arguments = args.partition { |arg| arg.is_a?(Array) || arg.is_a?(Operator) }
40
161
  @values = args
162
+
163
+ scope.nest(self) do
164
+ create_upstreams
165
+ end
166
+ end
167
+
168
+ def create_upstreams
169
+ @upstreams.map!{|stmt| to_op(stmt)}
170
+ end
171
+
172
+ def to_op(stmt)
173
+ stmt.is_a?(Operator) ? stmt : nodifier.create(*stmt)
174
+ end
175
+
176
+ def operator_name
177
+ self.class.just_class_name.underscore
178
+ end
179
+
180
+ def required_columns
181
+ self.class.required_columns
182
+ end
183
+
184
+ def dynamic_columns
185
+ scope.query_columns
186
+ end
187
+
188
+ def annotate(db, opts = {})
189
+ return @annotation if defined?(@annotation)
190
+
191
+ scope_key = options[:id]||self.class.just_class_name.underscore
192
+ annotation = {}
193
+ counts = (annotation[:counts] ||= {})
194
+ metadata = {:annotation=>annotation}
195
+ if name = self.class.preferred_name
196
+ metadata[:name] = name
197
+ end
198
+ res = [operator_name, *annotate_values(db, opts)]
199
+
200
+ if upstreams_valid?(db, opts) && scope.valid? && include_counts?(db, opts)
201
+ scope.with_ctes(evaluate(db), db)
202
+ .from_self
203
+ .select_group(:criterion_domain)
204
+ .select_append{count{}.*.as(:rows)}
205
+ .select_append{count(:person_id).distinct.as(:n)}
206
+ .each do |h|
207
+ counts[h.delete(:criterion_domain).to_sym] = h
208
+ end
209
+ elsif !errors.empty?
210
+ annotation[:errors] = errors
211
+ scope.add_errors(scope_key, errors)
212
+ end
213
+ scope.add_operators(self)
214
+ domains(db).each do |domain|
215
+ cur_counts = counts[domain] ||= {:rows=>0, :n=>0}
216
+ scope.add_counts(scope_key, domain, cur_counts)
217
+ end
218
+
219
+ if defined?(@warnings) && !warnings.empty?
220
+ annotation[:warnings] = warnings
221
+ scope.add_warnings(scope_key, warnings)
222
+ end
223
+
224
+ if res.last.is_a?(Hash)
225
+ res.last.merge!(metadata)
226
+ else
227
+ res << metadata
228
+ end
229
+
230
+ @annotation = res
41
231
  end
42
232
 
43
- def scope=(scope)
44
- @scope = scope
45
- scope.add_operator(self)
233
+ def code_list(db)
234
+ code_lists = @upstreams.map do | upstream_op |
235
+ upstream_op.code_list(db)
236
+ end
237
+ code_lists.flatten(1)
238
+ end
239
+
240
+ def dup_values(args)
241
+ self.class.new(nodifier, *args)
242
+ end
243
+
244
+ def inspect
245
+ "<##{self.class} upstreams=[#{upstreams.map(&:inspect).join(', ')}] arguments=[#{arguments.map(&:inspect).join(', ')}]>"
46
246
  end
47
247
 
48
248
  def evaluate(db)
@@ -53,106 +253,251 @@ module ConceptQL
53
253
  evaluate(db).sql
54
254
  end
55
255
 
56
- def select_it(query, specific_type = nil)
57
- specific_type = type if specific_type.nil? && respond_to?(:type)
58
- q = query.select(*columns(query, specific_type))
256
+ def optimized
257
+ dup_values(values.map{|x| x.is_a?(Operator) ? x.optimized : x})
258
+ end
259
+
260
+ def unionable?(other)
261
+ false
262
+ end
263
+
264
+ def select_it(query, specific_domain = nil)
265
+ if specific_domain.nil? && respond_to?(:domain) && TABLE_COLUMNS.keys.include?(domain)
266
+ specific_domain = domain
267
+ end
268
+
269
+ q = setup_select(query, specific_domain)
270
+
59
271
  if scope && scope.person_ids && upstreams.empty?
60
272
  q = q.where(person_id: scope.person_ids).from_self
61
273
  end
274
+
62
275
  q
63
276
  end
64
277
 
65
- def types
66
- @types ||= determine_types
278
+ def domains(db)
279
+ @domains ||= determine_domains(db)
67
280
  end
68
281
 
69
282
  def stream
70
283
  @stream ||= upstreams.first
71
284
  end
72
285
 
73
- def columns(query, local_type = nil)
74
- criterion_type = :criterion_type
75
- if local_type
76
- criterion_type = Sequel.cast_string(local_type.to_s).as(:criterion_type)
286
+ def setup_select(query, local_domain = nil)
287
+ query = modify_query(query, local_domain)
288
+ query.select(*columns(query, local_domain))
289
+ end
290
+
291
+ def columns(query, local_domain)
292
+ criterion_domain = :criterion_domain
293
+
294
+ if local_domain
295
+ criterion_domain = cast_column(:criterion_domain, local_domain.to_s)
77
296
  end
297
+
78
298
  columns = [:person_id,
79
- type_id(local_type),
80
- criterion_type]
81
- columns += date_columns(query, local_type)
82
- columns += value_columns(query, local_type)
299
+ domain_id(local_domain),
300
+ criterion_domain]
301
+ columns += date_columns(query, local_domain)
302
+ columns += [ source_value(query, local_domain) ]
303
+ columns += additional_columns(query, local_domain)
83
304
  end
84
305
 
85
306
  def label
86
- options[:label]
307
+ @label ||= begin
308
+ options.delete(:label) if options[:label] && options[:label].to_s.strip.empty?
309
+ options[:label].respond_to?(:strip) ? options[:label].strip : options[:label]
310
+ end
311
+ end
312
+
313
+ attr :errors, :warnings
314
+
315
+ def valid?(db, opts = {})
316
+ return @errors.empty? if defined?(@errors)
317
+ @errors = []
318
+ @warnings = []
319
+ validate(db, opts)
320
+ errors.empty?
321
+ end
322
+
323
+ def upstreams_valid?(db, opts = {})
324
+ valid?(db, opts) && upstreams.all?{|u| u.upstreams_valid?(db, opts)}
325
+ end
326
+
327
+ def scope
328
+ nodifier.scope
329
+ end
330
+
331
+ def data_model
332
+ nodifier.data_model
333
+ end
334
+
335
+ def database_type
336
+ nodifier.database_type
337
+ end
338
+
339
+ def cast_column(column, value = nil)
340
+ type = Scope::COLUMN_TYPES.fetch(column)
341
+ case type
342
+ when String, :String
343
+ Sequel.cast_string(value).as(column)
344
+ when Date, :Date
345
+ Sequel.cast(value, type).as(column)
346
+ when Float, :Bigint, :Float
347
+ Sequel.cast_numeric(value, type).as(column)
348
+ else
349
+ raise "Unexpected type: '#{type.inspect}' for column: '#{column}'"
350
+ end
87
351
  end
88
352
 
89
353
  private
90
- attr :scope
354
+
355
+ def annotate_values(db, opts)
356
+ (upstreams.map { |op| op.annotate(db, opts) } + arguments).push(options)
357
+ end
91
358
 
92
359
  def criterion_id
93
360
  :criterion_id
94
361
  end
95
362
 
96
- def type_id(type = nil)
97
- return :criterion_id if type.nil?
98
- type = :person if type == :death
99
- Sequel.expr(make_type_id(type)).as(:criterion_id)
363
+ def domain_id(domain = nil)
364
+ return :criterion_id if domain.nil?
365
+ domain = :person if domain == :death
366
+ Sequel.expr(make_domain_id(domain)).as(:criterion_id)
100
367
  end
101
368
 
102
- def make_type_id(type)
103
- (type.to_s + '_id').to_sym
369
+ def make_domain_id(domain)
370
+ (domain.to_s + '_id').to_sym
104
371
  end
105
372
 
106
373
  def make_table_name(table)
107
374
  "#{table}___tab".to_sym
108
375
  end
109
376
 
110
- def value_columns(query, type)
111
- [
112
- numeric_value(query),
113
- string_value(query),
114
- concept_id_value(query),
115
- units_source_value(query),
116
- source_value(query, type)
117
- ]
377
+ def query_cols
378
+ raise NotImplementedError, self
379
+ end
380
+
381
+ def query_columns(query)
382
+ unless cols = query.opts[:force_columns]
383
+ cols = query_cols
384
+ end
385
+
386
+ if ENV['CONCEPTQL_CHECK_COLUMNS']
387
+ if cols.sort != query.columns.sort
388
+ raise "columns don't match:\nclass: #{self.class}\nexpected: #{cols}\nactual: #{query.columns}\nvalues: #{values}\nSQL: #{query.sql}"
389
+ end
390
+ end
391
+
392
+ cols
393
+ end
394
+
395
+ def omopv4_plus?
396
+ data_model == :omopv4_plus
118
397
  end
119
398
 
120
- def numeric_value(query)
121
- return :value_as_number if query.columns.include?(:value_as_number)
122
- Sequel.cast_numeric(nil, Float).as(:value_as_number)
399
+ def omopv4?
400
+ data_model == :omopv4
123
401
  end
124
402
 
125
- def string_value(query)
126
- return :value_as_string if query.columns.include?(:value_as_string)
127
- Sequel.cast_string(nil).as(:value_as_string)
403
+ def impala?
404
+ database_type.to_sym == :impala
128
405
  end
129
406
 
130
- def concept_id_value(query)
131
- return :value_as_concept_id if query.columns.include?(:value_as_concept_id)
132
- Sequel.cast_numeric(nil).as(:value_as_concept_id)
407
+ def table_to_sym(table)
408
+ case table
409
+ when Symbol
410
+ table = Sequel.split_symbol(table)[1].to_sym
411
+ end
412
+ table
133
413
  end
134
414
 
135
- def units_source_value(query)
136
- return :units_source_value if query.columns.include?(:units_source_value)
137
- Sequel.cast_string(nil).as(:units_source_value)
415
+ def table_cols(table)
416
+ table = table_to_sym(table)
417
+ cols = TABLE_COLUMNS.fetch(table)
418
+ if omopv4_plus?
419
+ cols += Array(table_vocabulary_id(table))
420
+ end
421
+ cols
138
422
  end
139
423
 
140
- def source_value(query, type)
141
- return :source_value if query.columns.include?(:source_value)
142
- Sequel.cast_string(source_value_column(query, type)).as(:source_value)
424
+ def table_columns(*tables)
425
+ tables.map{|t| table_cols(t)}.flatten
143
426
  end
144
427
 
145
- def date_columns(query, type = nil)
146
- return [:start_date, :end_date] if (query.columns.include?(:start_date) && query.columns.include?(:end_date))
147
- return [:start_date, :end_date] unless type
148
- sd = start_date_column(query, type)
149
- sd = Sequel.expr(sd).cast(:date).as(:start_date) unless sd == :start_date
150
- ed = end_date_column(query, type)
151
- ed = Sequel.function(:coalesce, Sequel.expr(ed).cast(:date), Sequel.expr(start_date_column(query, type))).as(:end_date) unless ed == :end_date
428
+ def table_source_value(table)
429
+ TABLE_SOURCE_VALUE_COLUMN.fetch(table_to_sym(table))
430
+ end
431
+
432
+ def table_vocabulary_id(table)
433
+ TABLE_VOCABULARY_ID_COLUMN[table_to_sym(table)]
434
+ end
435
+
436
+ def additional_columns(query, domain)
437
+ special_columns = {
438
+ provenance_type: Proc.new { provenance_type(query, domain) },
439
+ provider_id: Proc.new { provider_id(query, domain) },
440
+ place_of_service_concept_id: Proc.new { place_of_service_concept_id(query, domain) }
441
+ }
442
+
443
+ additional_cols = special_columns.each_with_object([]) do |(column, proc_obj), columns|
444
+ columns << proc_obj.call if dynamic_columns.include?(column)
445
+ end
446
+
447
+ standard_columns = dynamic_columns - Scope::DEFAULT_COLUMNS.keys
448
+ standard_columns -= special_columns.keys
449
+
450
+ standard_columns.each do |column|
451
+ additional_cols << if query_columns(query).include?(column)
452
+ column
453
+ else
454
+ cast_column(column)
455
+ end
456
+ end
457
+
458
+ additional_cols
459
+ end
460
+
461
+ def source_value(query, domain)
462
+ return :source_value if query_columns(query).include?(:source_value)
463
+ cast_column(:source_value, source_value_column(query, domain))
464
+ end
465
+
466
+ def provenance_type(query, domain)
467
+ return :provenance_type if query_columns(query).include?(:provenance_type)
468
+ cast_column(:provenance_type, provenance_type_column(query, domain))
469
+ end
470
+
471
+ def provider_id(query, domain)
472
+ return :provider_id if query_columns(query).include?(:provider_id)
473
+ cast_column(:provider_id, provider_id_column(query, domain))
474
+ end
475
+
476
+ def place_of_service_concept_id(query, domain)
477
+ return :place_of_service_concept_id if query_columns(query).include?(:place_of_service_concept_id)
478
+ cast_column(:place_of_service_concept_id, place_of_service_concept_id_column(query, domain))
479
+ end
480
+
481
+ def date_columns(query, domain = nil)
482
+ return [:start_date, :end_date] if (query_columns(query).include?(:start_date) && query_columns(query).include?(:end_date))
483
+ return [:start_date, :end_date] unless domain
484
+
485
+ date_klass = Date
486
+ if query.db.database_type == :impala
487
+ date_klass = DateTime
488
+ end
489
+
490
+ sd = start_date_column(query, domain)
491
+ sd = Sequel.cast(Sequel.expr(sd), date_klass).as(:start_date) unless sd == :start_date
492
+ ed = end_date_column(query, domain)
493
+ ed = Sequel.cast(Sequel.function(:coalesce, Sequel.expr(ed), start_date_column(query, domain)), date_klass).as(:end_date) unless ed == :end_date
152
494
  [sd, ed]
153
495
  end
154
496
 
155
- def start_date_column(query, type)
497
+ # TODO: Move these hashes into a configuration file
498
+ # THey are OMOP-specific bits of information and need to be abstracted away
499
+
500
+ def start_date_column(query, domain)
156
501
  {
157
502
  condition_occurrence: :condition_start_date,
158
503
  death: :death_date,
@@ -165,10 +510,10 @@ module ConceptQL
165
510
  observation: :observation_date,
166
511
  observation_period: :observation_period_start_date,
167
512
  visit_occurrence: :visit_start_date
168
- }[type]
513
+ }[domain]
169
514
  end
170
515
 
171
- def end_date_column(query, type)
516
+ def end_date_column(query, domain)
172
517
  {
173
518
  condition_occurrence: :condition_end_date,
174
519
  death: :death_date,
@@ -181,10 +526,10 @@ module ConceptQL
181
526
  observation: :observation_date,
182
527
  observation_period: :observation_period_end_date,
183
528
  visit_occurrence: :visit_end_date
184
- }[type]
529
+ }[domain]
185
530
  end
186
531
 
187
- def source_value_column(query, type)
532
+ def source_value_column(query, domain)
188
533
  {
189
534
  condition_occurrence: :condition_source_value,
190
535
  death: :cause_of_death_source_value,
@@ -197,7 +542,61 @@ module ConceptQL
197
542
  observation: :observation_source_value,
198
543
  observation_period: nil,
199
544
  visit_occurrence: :place_of_service_source_value
200
- }[type]
545
+ }[domain]
546
+ end
547
+
548
+ def provenance_type_column(query, domain)
549
+ {
550
+ condition_occurrence: :condition_type_concept_id,
551
+ death: :death_type_concept_id,
552
+ drug_exposure: :drug_type_concept_id,
553
+ observation: :observation_type_concept_id,
554
+ procedure_occurrence: :procedure_type_concept_id
555
+ }[domain]
556
+ end
557
+
558
+ def provenance_type_column(query, domain)
559
+ {
560
+ condition_occurrence: :condition_type_concept_id,
561
+ death: :death_type_concept_id,
562
+ drug_exposure: :drug_type_concept_id,
563
+ observation: :observation_type_concept_id,
564
+ procedure_occurrence: :procedure_type_concept_id
565
+ }[domain]
566
+ end
567
+
568
+ def provider_id_column(query, domain)
569
+ {
570
+ condition_occurrence: :associated_provider_id,
571
+ death: :death_type_concept_id,
572
+ drug_exposure: :prescribing_provider_id,
573
+ observation: :associated_provider_id,
574
+ person: :provider_id,
575
+ procedure_occurrence: :associated_provider_id,
576
+ provider: :provider_id
577
+ }[domain]
578
+ end
579
+
580
+ def place_of_service_concept_id_column(query, domain)
581
+ return nil if domain.nil?
582
+ return :place_of_service_concept_id if table_cols(domain).include?(:visit_occurrence_id)
583
+ return nil
584
+ end
585
+
586
+ def modify_query(query, domain)
587
+ {
588
+ place_of_service_concept_id: ConceptQL::QueryModifiers::PoSQueryModifier,
589
+ drug_name: ConceptQL::QueryModifiers::DrugQueryModifier
590
+ }.each do |column, klass|
591
+ #p [domain, column, table, join_id, source_column]
592
+ #p dynamic_columns
593
+ #p query_cols
594
+ next if domain.nil?
595
+ next unless dynamic_columns.include?(column)
596
+ query = klass.new(query, self).modified_query
597
+ end
598
+
599
+ query
201
600
  end
202
601
 
203
602
  def person_date_of_birth(query)
@@ -206,31 +605,165 @@ module ConceptQL
206
605
 
207
606
  def assemble_date(query, *symbols)
208
607
  strings = symbols.map do |symbol|
209
- Sequel.cast_string(Sequel.function(:coalesce, Sequel.cast_string(symbol), Sequel.cast_string('01')))
608
+ sub = '2000'
609
+ col = Sequel.cast_string(symbol)
610
+ if symbol != :year_of_birth
611
+ sub = '01'
612
+ col = Sequel.function(:lpad, col, 2, '0')
613
+ end
614
+ Sequel.function(:coalesce, col, Sequel.expr(sub))
210
615
  end
211
- strings = strings.zip(['-'] * (symbols.length - 1)).flatten.compact
212
- concatted_strings = Sequel.join(strings)
213
- case query.db.database_type
616
+
617
+ strings_with_dashes = strings.zip(['-'] * (symbols.length - 1)).flatten.compact
618
+ concatted_strings = Sequel.join(strings_with_dashes)
619
+
620
+ date = concatted_strings
621
+ if query.db.database_type == :impala
622
+ date = Sequel.cast(Sequel.function(:concat_ws, '-', *strings), DateTime)
623
+ end
624
+ cast_date(query.db, date)
625
+ end
626
+
627
+ def cast_date(db, date)
628
+ case db.database_type
214
629
  when :oracle
215
- Sequel.function(:to_date, concatted_strings, 'YYYY-MM-DD')
630
+ Sequel.function(:to_date, date, 'YYYY-MM-DD')
216
631
  when :mssql
217
- Sequel.lit('CONVERT(DATETIME, ?)', concatted_strings)
632
+ Sequel.lit('CONVERT(DATETIME, ?)', date)
218
633
  else
219
- Sequel.cast(concatted_strings, Date)
634
+ Sequel.cast(date, Date)
220
635
  end
221
636
  end
222
637
 
223
- def determine_types
638
+ def determine_domains(db)
224
639
  if upstreams.empty?
225
- if respond_to?(:type)
226
- [type]
640
+ if respond_to?(:domain)
641
+ [domain]
227
642
  else
228
- raise "Operator doesn't seem to specify any type"
643
+ [:invalid]
229
644
  end
230
645
  else
231
- upstreams.map(&:types).flatten.uniq
646
+ doms = upstreams.compact.flat_map { |up| up.domains(db) }.uniq
647
+ doms.empty? ? [:invalid] : doms
232
648
  end
233
649
  end
650
+
651
+ # Validation Related
652
+
653
+ def upstream_operator_names
654
+ @upstreams.map(&:operator_name)
655
+ end
656
+
657
+ def validate(db, opts = {})
658
+ add_error("invalid label") if label && !label.is_a?(String)
659
+ self.class.validations.each do |args|
660
+ send(*args)
661
+ end
662
+ end
663
+
664
+ def validate_no_upstreams
665
+ add_error("has upstreams", upstream_operator_names) unless @upstreams.empty?
666
+ end
667
+
668
+ def validate_one_upstream
669
+ validate_at_least_one_upstream
670
+ validate_at_most_one_upstream
671
+ end
672
+
673
+ def validate_at_most_one_upstream
674
+ add_error("has multiple upstreams", upstream_operator_names) if @upstreams.length > 1
675
+ end
676
+
677
+ def validate_at_least_one_upstream
678
+ add_error("has no upstream") if @upstreams.empty?
679
+ end
680
+
681
+ def validate_no_arguments
682
+ add_error("has arguments", @arguments) unless @arguments.empty?
683
+ end
684
+
685
+ def validate_one_argument
686
+ validate_at_least_one_argument
687
+ validate_at_most_one_argument
688
+ end
689
+
690
+ def validate_at_most_one_argument
691
+ add_error("has multiple arguments", @arguments) if @arguments.length > 1
692
+ end
693
+
694
+ def validate_at_least_one_argument
695
+ add_error("has no arguments") if @arguments.empty?
696
+ end
697
+
698
+ def validate_option(format, *opts)
699
+ opts.each do |opt|
700
+ if options.has_key?(opt)
701
+ unless format === options[opt]
702
+ add_error("wrong option format", opt.to_s)
703
+ end
704
+ end
705
+ end
706
+ end
707
+
708
+ def validate_required_options(*opts)
709
+ opts.each do |opt|
710
+ unless options.has_key?(opt)
711
+ add_error("required option not present", opt.to_s)
712
+ end
713
+ end
714
+ end
715
+
716
+ def bad_arguments
717
+ return [] unless self.class.codes_regexp
718
+ @bad_arguments ||= arguments.reject do |arg|
719
+ self.class.codes_regexp === arg
720
+ end
721
+ end
722
+
723
+ def validate_codes_match
724
+ unless bad_arguments.empty?
725
+ add_warning("improperly formatted code", *bad_arguments)
726
+ end
727
+ end
728
+
729
+ def add_warnings?(db, opts = {})
730
+ @errors.empty? && db && db.adapter_scheme != :mock && !opts[:skip_db]
731
+ end
732
+
733
+ def add_error(*args)
734
+ errors << args
735
+ end
736
+
737
+ def add_warning(*args)
738
+ warnings << args
739
+ end
740
+
741
+ def needs_arguments_cte?(args)
742
+ impala? && arguments.length > 5000
743
+ end
744
+
745
+ def arguments_fix(db, args = nil)
746
+ args ||= arguments
747
+ return args unless needs_arguments_cte?(args)
748
+ args = args.dup
749
+ first_arg = Sequel.expr(args.shift).as(:arg)
750
+ args.unshift(first_arg)
751
+ args = args.map { |v| [v] }
752
+ args_cte = db.values(args)
753
+ db[:args]
754
+ .with(:args, args_cte)
755
+ .select(:arg)
756
+ end
757
+
758
+ def include_counts?(db, opts)
759
+ db && !opts[:skip_db] && !opts[:skip_counts]
760
+ end
234
761
  end
235
762
  end
236
763
  end
764
+
765
+ # Require all operator subclasses eagerly
766
+ Dir.new(File.dirname(__FILE__)).
767
+ entries.
768
+ each{|filename| require_relative filename if filename =~ /\.rb\z/ && filename != File.basename(__FILE__)}
769
+ ConceptQL::Operators.operators.values.each(&:freeze)