conceptql 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)