cehrbert-data 0.0.1__tar.gz → 0.0.3__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 (135) hide show
  1. cehrbert_data-0.0.3/.github/workflows/python-build.yml +93 -0
  2. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/PKG-INFO +1 -1
  3. cehrbert_data-0.0.3/src/cehrbert_data/apps/generate_required_labs.py +140 -0
  4. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/apps/generate_training_data.py +56 -36
  5. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/spark_app_base.py +144 -125
  6. cehrbert_data-0.0.3/src/cehrbert_data/const/artificial_tokens.py +3 -0
  7. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/const/common.py +5 -0
  8. cehrbert_data-0.0.3/src/cehrbert_data/decorators/__init__.py +5 -0
  9. cehrbert_data-0.0.3/src/cehrbert_data/decorators/artificial_time_token_decorator.py +336 -0
  10. cehrbert_data-0.0.3/src/cehrbert_data/decorators/clinical_event_decorator.py +168 -0
  11. cehrbert_data-0.0.3/src/cehrbert_data/decorators/death_event_decorator.py +114 -0
  12. cehrbert_data-0.0.3/src/cehrbert_data/decorators/demographic_event_decorator.py +111 -0
  13. cehrbert_data-0.0.3/src/cehrbert_data/decorators/patient_event_decorator_base.py +146 -0
  14. cehrbert_data-0.0.3/src/cehrbert_data/decorators/token_priority.py +22 -0
  15. cehrbert_data-0.0.1/src/cehrbert_data/queries/measurement_unit_stats_query.py → cehrbert_data-0.0.3/src/cehrbert_data/queries/measurement_queries.py +17 -2
  16. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/utils/spark_parse_args.py +21 -3
  17. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/utils/spark_utils.py +224 -133
  18. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data.egg-info/PKG-INFO +1 -1
  19. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data.egg-info/SOURCES.txt +12 -5
  20. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/tests/integration_tests/test_generate_training_data.py +2 -2
  21. cehrbert_data-0.0.3/tests/unit_tests/test_spark_utils.py +53 -0
  22. cehrbert_data-0.0.1/src/cehrbert_data/apps/generate_required_labs.py +0 -112
  23. cehrbert_data-0.0.1/src/cehrbert_data/decorators/__pycache__/__init__.cpython-311.pyc +0 -0
  24. cehrbert_data-0.0.1/src/cehrbert_data/decorators/__pycache__/patient_event_decorator.cpython-311.pyc +0 -0
  25. cehrbert_data-0.0.1/src/cehrbert_data/decorators/patient_event_decorator.py +0 -759
  26. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/.github/workflows/tests.yml +0 -0
  27. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/.gitignore +0 -0
  28. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/.pre-commit-config.yaml +0 -0
  29. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/LICENSE +0 -0
  30. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/README.md +0 -0
  31. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/pyproject.toml +0 -0
  32. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept/._SUCCESS.crc +0 -0
  33. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept/.part-00000-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet.crc +0 -0
  34. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept/.part-00003-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet.crc +0 -0
  35. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept/.part-00010-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet.crc +0 -0
  36. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept/_SUCCESS +0 -0
  37. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept/part-00000-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet +0 -0
  38. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept/part-00003-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet +0 -0
  39. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept/part-00010-4b12270c-f6c8-4b59-8e0f-fd588bd79386-c000.snappy.parquet +0 -0
  40. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/._SUCCESS.crc +0 -0
  41. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/.part-00000-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  42. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/.part-00002-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  43. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/.part-00006-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  44. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/.part-00011-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  45. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/.part-00013-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet.crc +0 -0
  46. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/_SUCCESS +0 -0
  47. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/part-00000-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  48. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/part-00002-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  49. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/part-00006-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  50. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/part-00011-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  51. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_ancestor/part-00013-eafbd8be-3337-46da-89d3-20f79c2565d4-c000.snappy.parquet +0 -0
  52. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/._SUCCESS.crc +0 -0
  53. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/.part-00000-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet.crc +0 -0
  54. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/.part-00002-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet.crc +0 -0
  55. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/.part-00007-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet.crc +0 -0
  56. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/.part-00012-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet.crc +0 -0
  57. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/_SUCCESS +0 -0
  58. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/part-00000-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet +0 -0
  59. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/part-00002-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet +0 -0
  60. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/part-00007-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet +0 -0
  61. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/concept_relationship/part-00012-5752b472-8ba7-4189-ab69-8c92e46443aa-c000.snappy.parquet +0 -0
  62. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/condition_occurrence/._SUCCESS.crc +0 -0
  63. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/condition_occurrence/.part-00000-4eff03a1-cdcf-4c89-b0cd-9ce590b9b1eb-c000.snappy.parquet.crc +0 -0
  64. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/condition_occurrence/_SUCCESS +0 -0
  65. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/condition_occurrence/part-00000-4eff03a1-cdcf-4c89-b0cd-9ce590b9b1eb-c000.snappy.parquet +0 -0
  66. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/drug_exposure/._SUCCESS.crc +0 -0
  67. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/drug_exposure/.part-00000-10bbf1a4-a7da-416e-9703-58609c7edfad-c000.snappy.parquet.crc +0 -0
  68. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/drug_exposure/_SUCCESS +0 -0
  69. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/drug_exposure/part-00000-10bbf1a4-a7da-416e-9703-58609c7edfad-c000.snappy.parquet +0 -0
  70. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/observation_period/._SUCCESS.crc +0 -0
  71. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/observation_period/.part-00000-694316e5-cc95-49f1-9fad-5a7f377e2602-c000.snappy.parquet.crc +0 -0
  72. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/observation_period/_SUCCESS +0 -0
  73. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/observation_period/part-00000-694316e5-cc95-49f1-9fad-5a7f377e2602-c000.snappy.parquet +0 -0
  74. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/person/._SUCCESS.crc +0 -0
  75. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/person/.part-00000-7d789011-f361-48da-af6f-cfe102978b3a-c000.snappy.parquet.crc +0 -0
  76. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/person/_SUCCESS +0 -0
  77. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/person/part-00000-7d789011-f361-48da-af6f-cfe102978b3a-c000.snappy.parquet +0 -0
  78. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/procedure_occurrence/._SUCCESS.crc +0 -0
  79. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/procedure_occurrence/.part-00000-e73003c1-aed5-41c0-b2d4-eaccaccf044a-c000.snappy.parquet.crc +0 -0
  80. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/procedure_occurrence/_SUCCESS +0 -0
  81. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/procedure_occurrence/part-00000-e73003c1-aed5-41c0-b2d4-eaccaccf044a-c000.snappy.parquet +0 -0
  82. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/visit_occurrence/._SUCCESS.crc +0 -0
  83. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/visit_occurrence/.part-00000-e874b5f1-bf9e-4cb9-93bf-c309a47b0476-c000.snappy.parquet.crc +0 -0
  84. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/visit_occurrence/_SUCCESS +0 -0
  85. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/sample_data/omop_sample/visit_occurrence/part-00000-e874b5f1-bf9e-4cb9-93bf-c309a47b0476-c000.snappy.parquet +0 -0
  86. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/setup.cfg +0 -0
  87. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/__init__.py +0 -0
  88. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/__init__.py +0 -0
  89. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/apps/__init__.py +0 -0
  90. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/apps/generate_concept_similarity_table.py +0 -0
  91. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/apps/generate_hierarchical_bert_training_data.py +0 -0
  92. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/apps/generate_included_concept_list.py +0 -0
  93. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/apps/generate_information_content.py +0 -0
  94. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/__init__.py +0 -0
  95. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/atrial_fibrillation.py +0 -0
  96. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/cabg.py +0 -0
  97. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/coronary_artery_disease.py +0 -0
  98. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/covid.py +0 -0
  99. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/covid_inpatient.py +0 -0
  100. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/death.py +0 -0
  101. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/heart_failure.py +0 -0
  102. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/ischemic_stroke.py +0 -0
  103. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/last_visit_discharged_home.py +0 -0
  104. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/query_builder.py +0 -0
  105. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/type_two_diabietes.py +0 -0
  106. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/cohorts/ventilation.py +0 -0
  107. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/config/__init__.py +0 -0
  108. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/config/output_names.py +0 -0
  109. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/const/__init__.py +0 -0
  110. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/const/__pycache__/__init__.cpython-311.pyc +0 -0
  111. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/const/__pycache__/common.cpython-311.pyc +0 -0
  112. {cehrbert_data-0.0.1/src/cehrbert_data/decorators → cehrbert_data-0.0.3/src/cehrbert_data/prediction_cohorts}/__init__.py +0 -0
  113. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/afib_ischemic_stroke.py +0 -0
  114. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/cad_cabg_cohort.py +0 -0
  115. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/cad_hf_cohort.py +0 -0
  116. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/copd_readmission.py +0 -0
  117. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/covid_death.py +0 -0
  118. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/covid_ventilation.py +0 -0
  119. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/discharge_home_death.py +0 -0
  120. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/hf_readmission.py +0 -0
  121. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/hospitalization.py +0 -0
  122. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/hospitalization_mortality.py +0 -0
  123. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/prediction_cohorts/t2dm_hf_cohort.py +0 -0
  124. {cehrbert_data-0.0.1/src/cehrbert_data/prediction_cohorts → cehrbert_data-0.0.3/src/cehrbert_data/queries}/__init__.py +0 -0
  125. {cehrbert_data-0.0.1/src/cehrbert_data/queries → cehrbert_data-0.0.3/src/cehrbert_data/tools}/__init__.py +0 -0
  126. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data/tools/download_omop_tables.py +0 -0
  127. {cehrbert_data-0.0.1/src/cehrbert_data/tools → cehrbert_data-0.0.3/src/cehrbert_data/utils}/__init__.py +0 -0
  128. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data.egg-info/dependency_links.txt +0 -0
  129. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data.egg-info/requires.txt +0 -0
  130. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/src/cehrbert_data.egg-info/top_level.txt +0 -0
  131. {cehrbert_data-0.0.1/src/cehrbert_data/utils → cehrbert_data-0.0.3/tests}/__init__.py +0 -0
  132. {cehrbert_data-0.0.1/tests → cehrbert_data-0.0.3/tests/integration_tests}/__init__.py +0 -0
  133. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/tests/integration_tests/test_hf_readmission.py +0 -0
  134. {cehrbert_data-0.0.1 → cehrbert_data-0.0.3}/tests/pyspark_test_base.py +0 -0
  135. {cehrbert_data-0.0.1/tests/integration_tests → cehrbert_data-0.0.3/tests/unit_tests}/__init__.py +0 -0
@@ -0,0 +1,93 @@
1
+ name: Publish Python 🐍 distribution 📦 to PyPI and TestPyPI
2
+
3
+ on: push
4
+
5
+ jobs:
6
+ build:
7
+ name: Build distribution 📦
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - uses: actions/checkout@v4
12
+ - name: Set up Python
13
+ uses: actions/setup-python@v4
14
+ with:
15
+ python-version: "3.x"
16
+ - name: Install pypa/build
17
+ run: >-
18
+ python3 -m
19
+ pip install
20
+ build
21
+ --user
22
+ - name: Build a binary wheel and a source tarball
23
+ run: python3 -m build
24
+ - name: Store the distribution packages
25
+ uses: actions/upload-artifact@v4
26
+ with:
27
+ name: python-package-distributions
28
+ path: dist/
29
+
30
+ publish-to-pypi:
31
+ name: >-
32
+ Publish Python 🐍 distribution 📦 to PyPI
33
+ if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
34
+ needs:
35
+ - build
36
+ runs-on: ubuntu-latest
37
+ environment:
38
+ name: pypi
39
+ url: https://pypi.org/p/cehrbert-data # Replace <package-name> with your PyPI project name
40
+ permissions:
41
+ id-token: write # IMPORTANT: mandatory for trusted publishing
42
+
43
+ steps:
44
+ - name: Download all the dists
45
+ uses: actions/download-artifact@v4
46
+ with:
47
+ name: python-package-distributions
48
+ path: dist/
49
+ - name: Publish distribution 📦 to PyPI
50
+ uses: pypa/gh-action-pypi-publish@release/v1
51
+
52
+ github-release:
53
+ name: >-
54
+ Sign the Python 🐍 distribution 📦 with Sigstore
55
+ and upload them to GitHub Release
56
+ needs:
57
+ - publish-to-pypi
58
+ runs-on: ubuntu-latest
59
+
60
+ permissions:
61
+ contents: write # IMPORTANT: mandatory for making GitHub Releases
62
+ id-token: write # IMPORTANT: mandatory for sigstore
63
+
64
+ steps:
65
+ - name: Download all the dists
66
+ uses: actions/download-artifact@v4
67
+ with:
68
+ name: python-package-distributions
69
+ path: dist/
70
+ - name: Sign the dists with Sigstore
71
+ uses: sigstore/gh-action-sigstore-python@v2.1.1
72
+ with:
73
+ inputs: >-
74
+ ./dist/*.tar.gz
75
+ ./dist/*.whl
76
+ - name: Create GitHub Release
77
+ env:
78
+ GITHUB_TOKEN: ${{ github.token }}
79
+ run: >-
80
+ gh release create
81
+ '${{ github.ref_name }}'
82
+ --repo '${{ github.repository }}'
83
+ --notes ""
84
+ - name: Upload artifact signatures to GitHub Release
85
+ env:
86
+ GITHUB_TOKEN: ${{ github.token }}
87
+ # Upload to GitHub Release using the `gh` CLI.
88
+ # `dist/` contains the built packages, and the
89
+ # sigstore-produced signatures and certificates.
90
+ run: >-
91
+ gh release upload
92
+ '${{ github.ref_name }}' dist/**
93
+ --repo '${{ github.repository }}'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cehrbert_data
3
- Version: 0.0.1
3
+ Version: 0.0.3
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
@@ -0,0 +1,140 @@
1
+ import argparse
2
+ import os
3
+
4
+ from pyspark.sql import SparkSession, DataFrame
5
+ from pyspark.sql import functions as F
6
+ from pyspark.sql.window import Window
7
+
8
+ from cehrbert_data.const.common import (
9
+ CONCEPT,
10
+ MEASUREMENT,
11
+ REQUIRED_MEASUREMENT,
12
+ NUMERIC_MEASUREMENT_STATS
13
+ )
14
+ from cehrbert_data.utils.spark_utils import preprocess_domain_table
15
+ from cehrbert_data.queries.measurement_queries import (
16
+ LAB_PREVALENCE_QUERY,
17
+ MEASUREMENT_UNIT_STATS_QUERY
18
+ )
19
+
20
+
21
+ def main(
22
+ input_folder,
23
+ output_folder,
24
+ num_of_numeric_labs,
25
+ num_of_categorical_labs,
26
+ min_num_of_patients
27
+ ):
28
+ spark = SparkSession.builder.appName("Generate required labs").getOrCreate()
29
+
30
+ # Load measurement as a dataframe in pyspark
31
+ measurement = preprocess_domain_table(spark, input_folder, MEASUREMENT)
32
+ # Load concept as a dataframe in pyspark
33
+ concept = preprocess_domain_table(spark, input_folder, CONCEPT)
34
+ # Create the local measurement view
35
+ measurement.createOrReplaceTempView(MEASUREMENT)
36
+ # Create the local concept view
37
+ concept.createOrReplaceTempView(CONCEPT)
38
+ # Create the
39
+ required_lab_dataframe = generate_required_labs(
40
+ spark, num_of_numeric_labs, num_of_categorical_labs, min_num_of_patients
41
+ )
42
+ required_lab_dataframe.write.mode("overwrite").parquet(
43
+ os.path.join(output_folder, REQUIRED_MEASUREMENT)
44
+ )
45
+ # Reload the dataframe from the disk
46
+ required_lab_dataframe = spark.read.parquet(
47
+ os.path.join(output_folder, REQUIRED_MEASUREMENT)
48
+ )
49
+ required_lab_dataframe.createOrReplaceTempView(REQUIRED_MEASUREMENT)
50
+ numeric_measurement_stats_dataframe = spark.sql(MEASUREMENT_UNIT_STATS_QUERY)
51
+ numeric_measurement_stats_dataframe.write.mode("overwrite").parquet(
52
+ os.path.join(output_folder, NUMERIC_MEASUREMENT_STATS)
53
+ )
54
+
55
+
56
+ def generate_required_labs(
57
+ spark: SparkSession,
58
+ num_of_numeric_labs: int,
59
+ num_of_categorical_labs: int,
60
+ min_num_of_patients: int
61
+ ) -> DataFrame:
62
+
63
+ prevalent_labs = spark.sql(LAB_PREVALENCE_QUERY)
64
+ prevalent_labs = prevalent_labs.where(F.col("person_count") >= min_num_of_patients)
65
+ # Cache the dataframe for faster computation in the below transformations
66
+ prevalent_labs.cache()
67
+ prevalent_numeric_labs = (
68
+ prevalent_labs.withColumn("is_numeric", F.col("numeric_percentage") >= 0.5)
69
+ .where("is_numeric")
70
+ .withColumn("rn", F.row_number().over(Window.orderBy(F.desc("freq"))))
71
+ .where(F.col("rn") <= num_of_numeric_labs)
72
+ .drop("rn")
73
+ )
74
+ prevalent_categorical_labs = (
75
+ prevalent_labs.withColumn("is_categorical", F.col("categorical_percentage") >= 0.5)
76
+ .where("is_categorical")
77
+ .withColumn("is_numeric", ~F.col("is_categorical"))
78
+ .withColumn("rn", F.row_number().over(Window.orderBy(F.desc("freq"))))
79
+ .where(F.col("rn") <= num_of_categorical_labs)
80
+ .drop("is_categorical")
81
+ .drop("rn")
82
+ )
83
+ return prevalent_numeric_labs.unionAll(prevalent_categorical_labs)
84
+
85
+
86
+ if __name__ == "__main__":
87
+ parser = argparse.ArgumentParser(description="Arguments for generate " "required labs to be included")
88
+ parser.add_argument(
89
+ "-i",
90
+ "--input_folder",
91
+ dest="input_folder",
92
+ action="store",
93
+ help="The path for your input_folder where the raw data is",
94
+ required=True,
95
+ )
96
+ parser.add_argument(
97
+ "-o",
98
+ "--output_folder",
99
+ dest="output_folder",
100
+ action="store",
101
+ help="The path for your output_folder",
102
+ required=True,
103
+ )
104
+ parser.add_argument(
105
+ "--num_of_numeric_labs",
106
+ dest="num_of_numeric_labs",
107
+ action="store",
108
+ type=int,
109
+ default=100,
110
+ help="The top most prevalent numeric labs to be included",
111
+ required=False,
112
+ )
113
+ parser.add_argument(
114
+ "--num_of_categorical_labs",
115
+ dest="num_of_categorical_labs",
116
+ action="store",
117
+ type=int,
118
+ default=100,
119
+ help="The top most prevalent categorical labs to be included",
120
+ required=False,
121
+ )
122
+ parser.add_argument(
123
+ "--min_num_of_patients",
124
+ dest="min_num_of_patients",
125
+ action="store",
126
+ type=int,
127
+ default=0,
128
+ help="Min no.of patients linked to concepts to be included",
129
+ required=False,
130
+ )
131
+
132
+ ARGS = parser.parse_args()
133
+
134
+ main(
135
+ ARGS.input_folder,
136
+ ARGS.output_folder,
137
+ ARGS.num_of_numeric_labs,
138
+ ARGS.num_of_categorical_labs,
139
+ ARGS.min_num_of_patients
140
+ )
@@ -8,39 +8,45 @@ from pyspark.sql import SparkSession
8
8
  from pyspark.sql import functions as F
9
9
  from pyspark.sql.window import Window
10
10
 
11
- from cehrbert_data.const.common import DEATH, MEASUREMENT, PERSON, REQUIRED_MEASUREMENT, VISIT_OCCURRENCE
12
- from cehrbert_data.decorators.patient_event_decorator import AttType
11
+ from cehrbert_data.const.common import (
12
+ PERSON,
13
+ VISIT_OCCURRENCE,
14
+ DEATH,
15
+ MEASUREMENT
16
+ )
17
+ from cehrbert_data.decorators import AttType
13
18
  from cehrbert_data.utils.spark_utils import (
14
19
  create_sequence_data,
15
20
  create_sequence_data_with_att,
16
21
  join_domain_tables,
17
22
  preprocess_domain_table,
18
- process_measurement,
23
+ get_measurement_table,
19
24
  validate_table_names,
20
25
  )
21
26
 
22
27
 
23
28
  def main(
24
- input_folder,
25
- output_folder,
26
- domain_table_list,
27
- date_filter,
28
- include_visit_type,
29
- is_new_patient_representation,
30
- exclude_visit_tokens,
31
- is_classic_bert,
32
- include_prolonged_stay,
33
- include_concept_list: bool,
34
- gpt_patient_sequence: bool,
35
- apply_age_filter: bool,
36
- include_death: bool,
37
- att_type: AttType,
38
- include_sequence_information_content: bool = False,
39
- exclude_demographic: bool = False,
40
- use_age_group: bool = False,
41
- with_drug_rollup: bool = True,
42
- include_inpatient_hour_token: bool = False,
43
- continue_from_events: bool = False,
29
+ input_folder,
30
+ output_folder,
31
+ domain_table_list,
32
+ date_filter,
33
+ include_visit_type,
34
+ is_new_patient_representation,
35
+ exclude_visit_tokens,
36
+ is_classic_bert,
37
+ include_prolonged_stay,
38
+ include_concept_list: bool,
39
+ gpt_patient_sequence: bool,
40
+ apply_age_filter: bool,
41
+ include_death: bool,
42
+ att_type: AttType,
43
+ include_sequence_information_content: bool = False,
44
+ exclude_demographic: bool = False,
45
+ use_age_group: bool = False,
46
+ with_drug_rollup: bool = True,
47
+ include_inpatient_hour_token: bool = False,
48
+ continue_from_events: bool = False,
49
+ refresh_measurement: bool = False
44
50
  ):
45
51
  spark = SparkSession.builder.appName("Generate CEHR-BERT Training Data").getOrCreate()
46
52
 
@@ -63,6 +69,7 @@ def main(
63
69
  f"exclude_demographic: {exclude_demographic}\n"
64
70
  f"use_age_group: {use_age_group}\n"
65
71
  f"with_drug_rollup: {with_drug_rollup}\n"
72
+ f"refresh_measurement: {refresh_measurement}\n"
66
73
  )
67
74
 
68
75
  domain_tables = []
@@ -117,17 +124,16 @@ def main(
117
124
 
118
125
  # Process the measurement table if exists
119
126
  if MEASUREMENT in domain_table_list:
120
- measurement = preprocess_domain_table(spark, input_folder, MEASUREMENT)
121
- required_measurement = preprocess_domain_table(spark, input_folder, REQUIRED_MEASUREMENT)
122
- # The select is necessary to make sure the order of the columns is the same as the
123
- # original dataframe, otherwise the union might use the wrong columns
124
- scaled_measurement = process_measurement(spark, measurement, required_measurement, output_folder)
125
-
127
+ processed_measurement = get_measurement_table(
128
+ spark,
129
+ input_folder,
130
+ refresh=refresh_measurement
131
+ )
126
132
  if patient_events:
127
133
  # Union all measurement records together with other domain records
128
- patient_events = patient_events.unionByName(scaled_measurement)
134
+ patient_events = patient_events.unionByName(processed_measurement)
129
135
  else:
130
- patient_events = scaled_measurement
136
+ patient_events = processed_measurement
131
137
 
132
138
  patient_events = (
133
139
  patient_events.join(visit_occurrence_person, "visit_occurrence_id")
@@ -206,17 +212,21 @@ def main(
206
212
  patient_splits_folder = os.path.join(input_folder, "patient_splits")
207
213
  if os.path.exists(patient_splits_folder):
208
214
  patient_splits = spark.read.parquet(patient_splits_folder)
209
- sequence_data.join(patient_splits, "person_id").write.mode("overwrite").parquet(
210
- os.path.join(output_folder, "patient_sequence", "temp")
215
+ temp_folder = os.path.join(output_folder, "patient_sequence", "temp")
216
+ sequence_data.join(
217
+ patient_splits.select("person_id", "split"),
218
+ "person_id"
219
+ ).write.mode("overwrite").parquet(
220
+ temp_folder
211
221
  )
212
- sequence_data = spark.read.parquet(os.path.join(output_folder, "patient_sequence", "temp"))
222
+ sequence_data = spark.read.parquet(temp_folder)
213
223
  sequence_data.where('split="train"').write.mode("overwrite").parquet(
214
224
  os.path.join(output_folder, "patient_sequence/train")
215
225
  )
216
226
  sequence_data.where('split="test"').write.mode("overwrite").parquet(
217
227
  os.path.join(output_folder, "patient_sequence/test")
218
228
  )
219
- shutil.rmtree(os.path.join(output_folder, "patient_sequence", "temp"))
229
+ shutil.rmtree(temp_folder)
220
230
  else:
221
231
  sequence_data.write.mode("overwrite").parquet(os.path.join(output_folder, "patient_sequence"))
222
232
 
@@ -304,7 +314,16 @@ if __name__ == "__main__":
304
314
  dest="include_inpatient_hour_token",
305
315
  action="store_true",
306
316
  )
307
- parser.add_argument("--continue_from_events", dest="continue_from_events", action="store_true")
317
+ parser.add_argument(
318
+ "--continue_from_events",
319
+ dest="continue_from_events",
320
+ action="store_true"
321
+ )
322
+ parser.add_argument(
323
+ "--refresh_measurement",
324
+ dest="refresh_measurement",
325
+ action="store_true"
326
+ )
308
327
  parser.add_argument(
309
328
  "--att_type",
310
329
  dest="att_type",
@@ -334,4 +353,5 @@ if __name__ == "__main__":
334
353
  with_drug_rollup=ARGS.with_drug_rollup,
335
354
  include_inpatient_hour_token=ARGS.include_inpatient_hour_token,
336
355
  continue_from_events=ARGS.continue_from_events,
356
+ refresh_measurement=ARGS.refresh_measurement,
337
357
  )