cehrbert-data 0.0.4__tar.gz → 0.0.6__tar.gz

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 (139) hide show
  1. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/.github/workflows/python-build.yml +2 -2
  2. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/.github/workflows/tests.yml +5 -0
  3. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/PKG-INFO +2 -2
  4. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/apps/generate_training_data.py +22 -2
  5. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/spark_app_base.py +98 -32
  6. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/decorators/artificial_time_token_decorator.py +146 -76
  7. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/decorators/clinical_event_decorator.py +45 -36
  8. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/decorators/death_event_decorator.py +24 -12
  9. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/decorators/demographic_event_decorator.py +38 -8
  10. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/decorators/patient_event_decorator_base.py +26 -2
  11. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/decorators/token_priority.py +9 -0
  12. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/hospitalization_mortality.py +4 -2
  13. cehrbert_data-0.0.6/src/cehrbert_data/tools/connect_omop_visit.py +288 -0
  14. cehrbert_data-0.0.6/src/cehrbert_data/tools/ehrshot_to_omop.py +952 -0
  15. cehrbert_data-0.0.6/src/cehrbert_data/tools/extract_features.py +297 -0
  16. cehrbert_data-0.0.6/src/cehrbert_data/tools/prepare_ehrshot_cohorts.py +22 -0
  17. cehrbert_data-0.0.6/src/cehrbert_data/tools/update_omop_visit.py +60 -0
  18. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/utils/spark_parse_args.py +40 -2
  19. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/utils/spark_utils.py +85 -41
  20. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data.egg-info/PKG-INFO +2 -2
  21. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data.egg-info/SOURCES.txt +7 -0
  22. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/tests/integration_tests/test_generate_training_data.py +2 -0
  23. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/tests/integration_tests/test_hf_readmission.py +2 -0
  24. cehrbert_data-0.0.6/tests/integration_tests/test_hf_readmission_cohort_meds.py +43 -0
  25. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/tests/pyspark_test_base.py +12 -2
  26. cehrbert_data-0.0.6/tests/unit_tests/test_ehrshot_to_omop.py +353 -0
  27. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/.gitignore +0 -0
  28. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/.pre-commit-config.yaml +0 -0
  29. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/LICENSE +0 -0
  30. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/README.md +0 -0
  31. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/pyproject.toml +0 -0
  32. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept/._SUCCESS.crc +0 -0
  33. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept/.part-00000-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet.crc +0 -0
  34. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept/.part-00003-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet.crc +0 -0
  35. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept/.part-00010-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet.crc +0 -0
  36. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept/_SUCCESS +0 -0
  37. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept/part-00000-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet +0 -0
  38. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept/part-00003-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet +0 -0
  39. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept/part-00010-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet +0 -0
  40. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/._SUCCESS.crc +0 -0
  41. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/.part-00000-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  42. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/.part-00002-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  43. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/.part-00006-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  44. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/.part-00011-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  45. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/.part-00013-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  46. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/_SUCCESS +0 -0
  47. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/part-00000-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  48. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/part-00002-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  49. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/part-00006-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  50. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/part-00011-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  51. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_ancestor/part-00013-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  52. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/._SUCCESS.crc +0 -0
  53. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/.part-00000-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet.crc +0 -0
  54. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/.part-00002-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet.crc +0 -0
  55. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/.part-00007-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet.crc +0 -0
  56. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/.part-00012-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet.crc +0 -0
  57. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/_SUCCESS +0 -0
  58. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/part-00000-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet +0 -0
  59. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/part-00002-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet +0 -0
  60. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/part-00007-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet +0 -0
  61. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/concept_relationship/part-00012-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet +0 -0
  62. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/condition_occurrence/._SUCCESS.crc +0 -0
  63. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/condition_occurrence/.part-00000-4eff03a1-cdcf-4c89-b0cd-9ce590b9b1eb-c000.snappy.parquet.crc +0 -0
  64. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/condition_occurrence/_SUCCESS +0 -0
  65. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/condition_occurrence/part-00000-4eff03a1-cdcf-4c89-b0cd-9ce590b9b1eb-c000.snappy.parquet +0 -0
  66. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/drug_exposure/._SUCCESS.crc +0 -0
  67. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/drug_exposure/.part-00000-10bbf1a4-a7da-416e-9703-58609c7edfad-c000.snappy.parquet.crc +0 -0
  68. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/drug_exposure/_SUCCESS +0 -0
  69. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/drug_exposure/part-00000-10bbf1a4-a7da-416e-9703-58609c7edfad-c000.snappy.parquet +0 -0
  70. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/observation_period/._SUCCESS.crc +0 -0
  71. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/observation_period/.part-00000-694316e5-cc95-49f1-9fad-5a7f377e2602-c000.snappy.parquet.crc +0 -0
  72. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/observation_period/_SUCCESS +0 -0
  73. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/observation_period/part-00000-694316e5-cc95-49f1-9fad-5a7f377e2602-c000.snappy.parquet +0 -0
  74. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/person/._SUCCESS.crc +0 -0
  75. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/person/.part-00000-7d789011-f361-48da-af6f-cfe102978b3a-c000.snappy.parquet.crc +0 -0
  76. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/person/_SUCCESS +0 -0
  77. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/person/part-00000-7d789011-f361-48da-af6f-cfe102978b3a-c000.snappy.parquet +0 -0
  78. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/procedure_occurrence/._SUCCESS.crc +0 -0
  79. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/procedure_occurrence/.part-00000-e73003c1-aed5-41c0-b2d4-eaccaccf044a-c000.snappy.parquet.crc +0 -0
  80. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/procedure_occurrence/_SUCCESS +0 -0
  81. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/procedure_occurrence/part-00000-e73003c1-aed5-41c0-b2d4-eaccaccf044a-c000.snappy.parquet +0 -0
  82. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/visit_occurrence/._SUCCESS.crc +0 -0
  83. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/visit_occurrence/.part-00000-e874b5f1-bf9e-4cb9-93bf-c309a47b0476-c000.snappy.parquet.crc +0 -0
  84. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/visit_occurrence/_SUCCESS +0 -0
  85. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/sample_data/omop_sample/visit_occurrence/part-00000-e874b5f1-bf9e-4cb9-93bf-c309a47b0476-c000.snappy.parquet +0 -0
  86. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/setup.cfg +0 -0
  87. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/__init__.py +0 -0
  88. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/__init__.py +0 -0
  89. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/apps/__init__.py +0 -0
  90. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/apps/generate_concept_similarity_table.py +0 -0
  91. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/apps/generate_hierarchical_bert_training_data.py +0 -0
  92. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/apps/generate_included_concept_list.py +0 -0
  93. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/apps/generate_information_content.py +0 -0
  94. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/apps/generate_required_labs.py +0 -0
  95. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/__init__.py +0 -0
  96. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/atrial_fibrillation.py +0 -0
  97. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/cabg.py +0 -0
  98. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/coronary_artery_disease.py +0 -0
  99. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/covid.py +0 -0
  100. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/covid_inpatient.py +0 -0
  101. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/death.py +0 -0
  102. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/heart_failure.py +0 -0
  103. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/ischemic_stroke.py +0 -0
  104. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/last_visit_discharged_home.py +0 -0
  105. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/query_builder.py +0 -0
  106. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/type_two_diabietes.py +0 -0
  107. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/cohorts/ventilation.py +0 -0
  108. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/config/__init__.py +0 -0
  109. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/config/output_names.py +0 -0
  110. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/const/__init__.py +0 -0
  111. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/const/__pycache__/__init__.cpython-311.pyc +0 -0
  112. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/const/__pycache__/common.cpython-311.pyc +0 -0
  113. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/const/artificial_tokens.py +0 -0
  114. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/const/common.py +0 -0
  115. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/decorators/__init__.py +0 -0
  116. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/__init__.py +0 -0
  117. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/afib_ischemic_stroke.py +0 -0
  118. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/cad_cabg_cohort.py +0 -0
  119. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/cad_hf_cohort.py +0 -0
  120. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/copd_readmission.py +0 -0
  121. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/covid_death.py +0 -0
  122. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/covid_ventilation.py +0 -0
  123. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/discharge_home_death.py +0 -0
  124. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/hf_readmission.py +0 -0
  125. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/hospitalization.py +0 -0
  126. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/prediction_cohorts/t2dm_hf_cohort.py +0 -0
  127. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/queries/__init__.py +0 -0
  128. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/queries/measurement_queries.py +0 -0
  129. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/tools/__init__.py +0 -0
  130. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/tools/download_omop_tables.py +0 -0
  131. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/utils/__init__.py +0 -0
  132. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data/utils/logging_utils.py +0 -0
  133. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data.egg-info/dependency_links.txt +0 -0
  134. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data.egg-info/requires.txt +0 -0
  135. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/src/cehrbert_data.egg-info/top_level.txt +0 -0
  136. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/tests/__init__.py +0 -0
  137. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/tests/integration_tests/__init__.py +0 -0
  138. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/tests/unit_tests/__init__.py +0 -0
  139. {cehrbert_data-0.0.4 → cehrbert_data-0.0.6}/tests/unit_tests/test_spark_utils.py +0 -0
@@ -68,7 +68,7 @@ jobs:
68
68
  name: python-package-distributions
69
69
  path: dist/
70
70
  - name: Sign the dists with Sigstore
71
- uses: sigstore/gh-action-sigstore-python@v2.1.1
71
+ uses: sigstore/gh-action-sigstore-python@v3.0.0
72
72
  with:
73
73
  inputs: >-
74
74
  ./dist/*.tar.gz
@@ -90,4 +90,4 @@ jobs:
90
90
  run: >-
91
91
  gh release upload
92
92
  '${{ github.ref_name }}' dist/**
93
- --repo '${{ github.repository }}'
93
+ --repo '${{ github.repository }}'
@@ -23,6 +23,11 @@ jobs:
23
23
  uses: actions/setup-python@v3
24
24
  with:
25
25
  python-version: "3.10"
26
+ - name: Set up Java 11
27
+ uses: actions/setup-java@v3
28
+ with:
29
+ java-version: "11" # specify the Java version here
30
+ distribution: "temurin" # or use 'adopt' or 'zulu', depending on your preference
26
31
  - name: Install dependencies
27
32
  run: |
28
33
  python -m pip install --upgrade pip
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: cehrbert_data
3
- Version: 0.0.4
3
+ Version: 0.0.6
4
4
  Summary: The Spark ETL tools for generating the CEHR-BERT and CEHR-GPT pre-training and finetuning data
5
5
  Author-email: Chao Pang <chaopang229@gmail.com>, Xinzhuo Jiang <xj2193@cumc.columbia.edu>, Krishna Kalluri <kk3326@cumc.columbia.edu>, Nishanth Parameshwar Pavinkurve <np2689@cumc.columbia.edu>, Karthik Natarajan <kn2174@cumc.columbia.edu>
6
6
  License: MIT License
@@ -41,13 +41,15 @@ def main(
41
41
  apply_age_filter: bool,
42
42
  include_death: bool,
43
43
  att_type: AttType,
44
+ inpatient_att_type: AttType,
44
45
  include_sequence_information_content: bool = False,
45
46
  exclude_demographic: bool = False,
46
47
  use_age_group: bool = False,
47
48
  with_drug_rollup: bool = True,
48
49
  include_inpatient_hour_token: bool = False,
49
50
  continue_from_events: bool = False,
50
- refresh_measurement: bool = False
51
+ refresh_measurement: bool = False,
52
+ aggregate_by_hour: bool = True,
51
53
  ):
52
54
  spark = SparkSession.builder.appName("Generate CEHR-BERT Training Data").getOrCreate()
53
55
 
@@ -71,6 +73,7 @@ def main(
71
73
  f"use_age_group: {use_age_group}\n"
72
74
  f"with_drug_rollup: {with_drug_rollup}\n"
73
75
  f"refresh_measurement: {refresh_measurement}\n"
76
+ f"aggregate_by_hour: {aggregate_by_hour}\n"
74
77
  )
75
78
 
76
79
  domain_tables = []
@@ -128,7 +131,8 @@ def main(
128
131
  processed_measurement = get_measurement_table(
129
132
  spark,
130
133
  input_folder,
131
- refresh=refresh_measurement
134
+ refresh=refresh_measurement,
135
+ aggregate_by_hour=aggregate_by_hour,
132
136
  )
133
137
  if patient_events:
134
138
  # Union all measurement records together with other domain records
@@ -165,9 +169,12 @@ def main(
165
169
  patient_demographic=person if gpt_patient_sequence else None,
166
170
  death=death,
167
171
  att_type=att_type,
172
+ inpatient_att_type=inpatient_att_type,
168
173
  exclude_demographic=exclude_demographic,
169
174
  use_age_group=use_age_group,
170
175
  include_inpatient_hour_token=include_inpatient_hour_token,
176
+ spark=spark,
177
+ persistence_folder=output_folder,
171
178
  )
172
179
  else:
173
180
  sequence_data = create_sequence_data(
@@ -325,12 +332,23 @@ if __name__ == "__main__":
325
332
  dest="refresh_measurement",
326
333
  action="store_true"
327
334
  )
335
+ parser.add_argument(
336
+ "--aggregate_by_hour",
337
+ dest="aggregate_by_hour",
338
+ action="store_true"
339
+ )
328
340
  parser.add_argument(
329
341
  "--att_type",
330
342
  dest="att_type",
331
343
  action="store",
332
344
  choices=[e.value for e in AttType],
333
345
  )
346
+ parser.add_argument(
347
+ "--inpatient_att_type",
348
+ dest="inpatient_att_type",
349
+ action="store",
350
+ choices=[e.value for e in AttType],
351
+ )
334
352
 
335
353
  ARGS = parser.parse_args()
336
354
 
@@ -352,10 +370,12 @@ if __name__ == "__main__":
352
370
  ARGS.apply_age_filter,
353
371
  ARGS.include_death,
354
372
  AttType(ARGS.att_type),
373
+ AttType(ARGS.inpatient_att_type),
355
374
  exclude_demographic=ARGS.exclude_demographic,
356
375
  use_age_group=ARGS.use_age_group,
357
376
  with_drug_rollup=ARGS.with_drug_rollup,
358
377
  include_inpatient_hour_token=ARGS.include_inpatient_hour_token,
359
378
  continue_from_events=ARGS.continue_from_events,
360
379
  refresh_measurement=ARGS.refresh_measurement,
380
+ aggregate_by_hour=ARGS.aggregate_by_hour,
361
381
  )
@@ -5,6 +5,7 @@ import shutil
5
5
  from abc import ABC
6
6
  from typing import List
7
7
 
8
+ from numpy.random import permutation
8
9
  from pandas import to_datetime
9
10
  from pyspark.sql import DataFrame, SparkSession
10
11
  from pyspark.sql import functions as F
@@ -246,6 +247,7 @@ class BaseCohortBuilder(ABC):
246
247
  def _add_demographics(self, cohort: DataFrame):
247
248
  return (
248
249
  cohort.join(self._dependency_dict[PERSON], "person_id")
250
+ .withColumn("year_of_birth", F.coalesce(F.year("birth_datetime"), F.col("year_of_birth")))
249
251
  .withColumn("age", F.year("index_date") - F.col("year_of_birth"))
250
252
  .select(
251
253
  F.col("person_id"),
@@ -295,6 +297,7 @@ class NestedCohortBuilder:
295
297
  is_drug_roll_up_concept: bool = True,
296
298
  include_concept_list: bool = True,
297
299
  refresh_measurement: bool = False,
300
+ aggregate_by_hour: bool = True,
298
301
  is_new_patient_representation: bool = False,
299
302
  gpt_patient_sequence: bool = False,
300
303
  is_hierarchical_bert: bool = False,
@@ -306,9 +309,14 @@ class NestedCohortBuilder:
306
309
  is_observation_window_unbounded: bool = False,
307
310
  is_population_estimation: bool = False,
308
311
  att_type: AttType = AttType.CEHR_BERT,
312
+ inpatient_att_type: AttType = AttType.MIX,
313
+ include_inpatient_hour_token: bool = False,
309
314
  exclude_demographic: bool = True,
310
315
  use_age_group: bool = False,
311
316
  single_contribution: bool = False,
317
+ exclude_features: bool = True,
318
+ meds_format: bool = False,
319
+ cache_events: bool = False,
312
320
  ):
313
321
  self._cohort_name = cohort_name
314
322
  self._input_folder = input_folder
@@ -340,15 +348,21 @@ class NestedCohortBuilder:
340
348
  self._is_prediction_window_unbounded = is_prediction_window_unbounded
341
349
  self._include_concept_list = include_concept_list
342
350
  self._refresh_measurement = refresh_measurement
351
+ self._aggregate_by_hour = aggregate_by_hour
343
352
  self._allow_measurement_only = allow_measurement_only
344
353
  self._output_data_folder = os.path.join(
345
354
  self._output_folder, re.sub("[^a-z0-9]+", "_", self._cohort_name.lower())
346
355
  )
347
356
  self._is_population_estimation = is_population_estimation
348
357
  self._att_type = att_type
358
+ self._inpatient_att_type = inpatient_att_type
359
+ self._include_inpatient_hour_token = include_inpatient_hour_token
349
360
  self._exclude_demographic = exclude_demographic
350
361
  self._use_age_group = use_age_group
351
362
  self._single_contribution = single_contribution
363
+ self._exclude_features = exclude_features
364
+ self._meds_format = meds_format
365
+ self._cache_events = cache_events
352
366
 
353
367
  self.get_logger().info(
354
368
  f"cohort_name: {cohort_name}\n"
@@ -377,12 +391,18 @@ class NestedCohortBuilder:
377
391
  f"is_prediction_window_unbounded: {is_prediction_window_unbounded}\n"
378
392
  f"include_concept_list: {include_concept_list}\n"
379
393
  f"refresh_measurement: {refresh_measurement}\n"
394
+ f"aggregate_by_hour: {aggregate_by_hour}\n"
380
395
  f"is_observation_window_unbounded: {is_observation_window_unbounded}\n"
381
396
  f"is_population_estimation: {is_population_estimation}\n"
382
397
  f"att_type: {att_type}\n"
398
+ f"inpatient_att_type: {inpatient_att_type}\n"
399
+ f"include_inpatient_hour_token: {include_inpatient_hour_token}\n"
383
400
  f"exclude_demographic: {exclude_demographic}\n"
384
401
  f"use_age_group: {use_age_group}\n"
385
402
  f"single_contribution: {single_contribution}\n"
403
+ f"extract_features: {exclude_features}\n"
404
+ f"meds_format: {meds_format}\n"
405
+ f"cache_events: {cache_events}\n"
386
406
  )
387
407
 
388
408
  self.spark = SparkSession.builder.appName(f"Generate {self._cohort_name}").getOrCreate()
@@ -508,13 +528,30 @@ class NestedCohortBuilder:
508
528
  )
509
529
  cohort = cohort.withColumn("record_rank", record_rank).where("record_rank == 1").drop("record_rank")
510
530
 
511
- ehr_records_for_cohorts = self.extract_ehr_records_for_cohort(cohort)
512
- # ehr_records_for_cohorts.show()
513
- cohort = (
514
- cohort.join(ehr_records_for_cohorts, ["person_id", "cohort_member_id"])
515
- .where(F.col("num_of_visits") >= self._num_of_visits)
516
- .where(F.col("num_of_concepts") >= self._num_of_concepts)
517
- )
531
+ if not self._exclude_features:
532
+ ehr_records_for_cohorts = self.extract_ehr_records_for_cohort(cohort)
533
+ cohort = (
534
+ cohort.join(ehr_records_for_cohorts, ["person_id", "cohort_member_id"])
535
+ .where(F.col("num_of_visits") >= self._num_of_visits)
536
+ .where(F.col("num_of_concepts") >= self._num_of_concepts)
537
+ )
538
+
539
+ person_id_column = "person_id"
540
+ index_date_column = "index_date"
541
+ if self._meds_format:
542
+ cohort = cohort.withColumnRenamed(
543
+ "person_id", "subject_id"
544
+ ).withColumnRenamed(
545
+ "index_date", "prediction_time"
546
+ ).withColumnRenamed(
547
+ "label", "boolean_value"
548
+ ).withColumn(
549
+ "prediction_time", F.to_timestamp("prediction_time")
550
+ ).withColumn(
551
+ "boolean_value", F.col("boolean_value").cast("boolean")
552
+ )
553
+ person_id_column = "subject_id"
554
+ index_date_column = "prediction_time"
518
555
 
519
556
  if self._is_prediction_window_unbounded:
520
557
  observation_period = self._dependency_dict[OBSERVATION_PERIOD]
@@ -529,16 +566,28 @@ class NestedCohortBuilder:
529
566
  # Add time_to_event
530
567
  cohort = cohort.withColumn(
531
568
  "study_end_date",
532
- F.coalesce(F.col("outcome_date"), F.date_add(cohort.index_date, self._prediction_window))
569
+ F.coalesce(
570
+ F.col("outcome_date"),
571
+ F.date_add(
572
+ cohort[index_date_column], self._prediction_window
573
+ )
574
+ )
533
575
  )
534
- cohort = cohort.withColumn("time_to_event", F.datediff("study_end_date", "index_date"))
576
+ cohort = cohort.withColumn("time_to_event", F.datediff("study_end_date", index_date_column))
535
577
 
536
578
  # if patient_splits is provided, we will
537
579
  if self._patient_splits_folder:
538
580
  patient_splits = self.spark.read.parquet(self._patient_splits_folder)
539
- cohort.join(patient_splits, "person_id").orderBy("person_id", "cohort_member_id").write.mode(
581
+ cohort.join(
582
+ patient_splits,
583
+ cohort[person_id_column] == patient_splits.person_id
584
+ ).select(
585
+ [cohort[c] for c in cohort.columns] + [patient_splits.split]
586
+ ).orderBy(person_id_column, index_date_column).write.mode(
540
587
  "overwrite"
541
- ).parquet(os.path.join(self._output_data_folder, "temp"))
588
+ ).parquet(
589
+ os.path.join(self._output_data_folder, "temp")
590
+ )
542
591
  # Reload the data from the disk
543
592
  cohort = self.spark.read.parquet(os.path.join(self._output_data_folder, "temp"))
544
593
  cohort.where('split="train"').write.mode("overwrite").parquet(
@@ -547,7 +596,7 @@ class NestedCohortBuilder:
547
596
  cohort.where('split="test"').write.mode("overwrite").parquet(os.path.join(self._output_data_folder, "test"))
548
597
  shutil.rmtree(os.path.join(self._output_data_folder, "temp"))
549
598
  else:
550
- cohort.orderBy("person_id", "cohort_member_id").write.mode("overwrite").parquet(self._output_data_folder)
599
+ cohort.orderBy(person_id_column, index_date_column).write.mode("overwrite").parquet(self._output_data_folder)
551
600
 
552
601
  def extract_ehr_records_for_cohort(self, cohort: DataFrame):
553
602
  """
@@ -566,47 +615,54 @@ class NestedCohortBuilder:
566
615
  with_drug_rollup=self._is_drug_roll_up_concept,
567
616
  include_concept_list=self._include_concept_list,
568
617
  refresh_measurement=self._refresh_measurement,
618
+ aggregate_by_hour=self._aggregate_by_hour,
569
619
  )
570
620
 
571
621
  # Duplicate the records for cohorts that allow multiple entries
572
- ehr_records = ehr_records.join(cohort, "person_id").select(
573
- [ehr_records[field_name] for field_name in ehr_records.schema.fieldNames()] + ["cohort_member_id"]
574
- )
622
+ ehr_records = ehr_records.alias("ehr").join(
623
+ cohort.alias("cohort"), F.col("ehr.person_id") == F.col("cohort.person_id")
624
+ ).select(
625
+ [F.col("ehr." + col) for col in ehr_records.columns] + [F.col("cohort.cohort_member_id")]
626
+ ).selectExpr("*")
575
627
 
576
628
  # Only allow the data records that occurred between the index date and the prediction window
577
629
  if self._is_population_estimation:
578
630
  if self._is_prediction_window_unbounded:
579
- record_window_filter = ehr_records["date"] <= F.current_date()
631
+ record_window_filter = F.col("ehr.date") <= F.current_date()
580
632
  else:
581
- record_window_filter = ehr_records["date"] <= F.date_add(cohort["index_date"], self._prediction_window)
633
+ record_window_filter = F.col("ehr.date") <= F.date_add(
634
+ F.col("cohort.index_date"), self._prediction_window
635
+ )
582
636
  else:
583
637
  # For patient level prediction, we remove all records post index date
584
638
  if self._is_observation_post_index:
585
- record_window_filter = ehr_records["date"].between(
586
- cohort["index_date"],
587
- F.date_add(cohort["index_date"], self._observation_window),
639
+ record_window_filter = F.col("ehr.date").between(
640
+ F.col("cohort.index_date"),
641
+ F.date_add(F.col("cohort.index_date"), self._observation_window),
588
642
  )
589
643
  else:
590
644
  if self._is_observation_window_unbounded:
591
- record_window_filter = ehr_records["date"] <= F.date_sub(
592
- cohort["index_date"], self._hold_off_window
645
+ record_window_filter = F.col("ehr.date") <= F.date_sub(
646
+ F.col("cohort.index_date"), self._hold_off_window
593
647
  )
594
648
  else:
595
- record_window_filter = ehr_records["date"].between(
649
+ record_window_filter = F.col("ehr.date").between(
596
650
  F.date_sub(
597
- cohort["index_date"],
651
+ F.col("cohort.index_date"),
598
652
  self._observation_window + self._hold_off_window,
599
653
  ),
600
- F.date_sub(cohort["index_date"], self._hold_off_window),
654
+ F.date_sub(F.col("cohort.index_date"), self._hold_off_window),
601
655
  )
602
656
 
603
- cohort_ehr_records = (
604
- ehr_records.join(
605
- cohort,
606
- (ehr_records.person_id == cohort.person_id) & (ehr_records.cohort_member_id == cohort.cohort_member_id),
607
- )
608
- .where(record_window_filter)
609
- .select([ehr_records[field_name] for field_name in ehr_records.schema.fieldNames()])
657
+ # Somehow the dataframe join does not work without using the alias
658
+ cohort_ehr_records = ehr_records.alias("ehr").join(
659
+ cohort.alias("cohort"),
660
+ (F.col("ehr.person_id") == F.col("cohort.person_id")) &
661
+ (F.col("ehr.cohort_member_id") == F.col("cohort.cohort_member_id")),
662
+ ).where(
663
+ record_window_filter
664
+ ).select(
665
+ [F.col("ehr." + field_name) for field_name in ehr_records.schema.fieldNames()]
610
666
  )
611
667
 
612
668
  if self._is_hierarchical_bert:
@@ -647,8 +703,12 @@ class NestedCohortBuilder:
647
703
  exclude_visit_tokens=self._exclude_visit_tokens,
648
704
  patient_demographic=(patient_demographic if self._gpt_patient_sequence else None),
649
705
  att_type=self._att_type,
706
+ inpatient_att_type=self._inpatient_att_type,
650
707
  exclude_demographic=self._exclude_demographic,
651
708
  use_age_group=self._use_age_group,
709
+ include_inpatient_hour_token=self._include_inpatient_hour_token,
710
+ spark=self.spark if self._cache_events else None,
711
+ persistence_folder=self._output_data_folder if self._cache_events else None,
652
712
  )
653
713
 
654
714
  return create_sequence_data(
@@ -720,6 +780,7 @@ def create_prediction_cohort(
720
780
  age_upper_bound=spark_args.age_upper_bound,
721
781
  prior_observation_period=0,
722
782
  post_observation_period=0,
783
+ continue_job=spark_args.continue_job,
723
784
  )
724
785
  .build()
725
786
  .load_cohort()
@@ -748,6 +809,7 @@ def create_prediction_cohort(
748
809
  is_drug_roll_up_concept=spark_args.is_drug_roll_up_concept,
749
810
  include_concept_list=spark_args.include_concept_list,
750
811
  refresh_measurement=spark_args.refresh_measurement,
812
+ aggregate_by_hour=spark_args.aggregate_by_hour,
751
813
  is_new_patient_representation=spark_args.is_new_patient_representation,
752
814
  gpt_patient_sequence=spark_args.gpt_patient_sequence,
753
815
  is_hierarchical_bert=spark_args.is_hierarchical_bert,
@@ -763,7 +825,11 @@ def create_prediction_cohort(
763
825
  is_observation_window_unbounded=spark_args.is_observation_window_unbounded,
764
826
  is_population_estimation=spark_args.is_population_estimation,
765
827
  att_type=AttType(spark_args.att_type),
828
+ inpatient_att_type=AttType(spark_args.inpatient_att_type),
829
+ include_inpatient_hour_token=spark_args.include_inpatient_hour_token,
766
830
  exclude_demographic=spark_args.exclude_demographic,
767
831
  use_age_group=spark_args.use_age_group,
768
832
  single_contribution=spark_args.single_contribution,
833
+ exclude_features=spark_args.exclude_features,
834
+ meds_format=spark_args.meds_format,
769
835
  ).build()