es-aces 0.2.0__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.
es_aces-0.2.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Justin Xu, Matthew McDermott
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
es_aces-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,168 @@
1
+ Metadata-Version: 2.1
2
+ Name: es-aces
3
+ Version: 0.2.0
4
+ Summary: Event Stream Automatic Cohort Extraction System (ACES)
5
+ Author-email: Justin Xu <justin13601@hotmail.com>, Matthew McDermott <mattmcdermott8@gmail.com>
6
+ Project-URL: Homepage, https://github.com/justin13601/ACES
7
+ Project-URL: Issues, https://github.com/justin13601/ACES/issues
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: polars==0.20.18
15
+ Requires-Dist: bigtree==0.17.0
16
+ Requires-Dist: ruamel.yaml==0.18.6
17
+ Requires-Dist: pandas==2.2.2
18
+ Requires-Dist: loguru==0.7.2
19
+ Requires-Dist: hydra-core==1.3.2
20
+ Requires-Dist: pytimeparse==1.1.8
21
+ Requires-Dist: networkx==3.3
22
+ Provides-Extra: dev
23
+ Requires-Dist: pre-commit; extra == "dev"
24
+ Requires-Dist: pytest; extra == "dev"
25
+ Requires-Dist: pytest-cov; extra == "dev"
26
+ Requires-Dist: pytest-subtests; extra == "dev"
27
+ Requires-Dist: rootutils; extra == "dev"
28
+ Provides-Extra: profiling
29
+ Requires-Dist: psutil; extra == "profiling"
30
+
31
+ # Event Stream Automatic Cohort Extraction System (ACES)
32
+
33
+ [![python](https://img.shields.io/badge/-Python_3.10-blue?logo=python&logoColor=white)](https://github.com/pre-commit/pre-commit)
34
+ [![hydra](https://img.shields.io/badge/Config-Hydra_1.3-89b8cd)](https://hydra.cc/)
35
+ [![codecov](https://codecov.io/gh/justin13601/ACES/graph/badge.svg?token=6EA84VFXOV)](https://codecov.io/gh/justin13601/ACES)
36
+ [![tests](https://github.com/justin13601/ACES/actions/workflows/tests.yml/badge.svg)](https://github.com/justin13601/ACES/actions/workflows/test.yml)
37
+ [![code-quality](https://github.com/justin13601/ACES/actions/workflows/code-quality-master.yaml/badge.svg)](https://github.com/justin13601/ACES/actions/workflows/code-quality-master.yaml)
38
+ [![Documentation Status](https://readthedocs.org/projects/eventstreamaces/badge/?version=latest)](https://eventstreamaces.readthedocs.io/en/latest/?badge=latest)
39
+ [![contributors](https://img.shields.io/github/contributors/justin13601/ACES.svg)](https://github.com/justin13601/ACES/graphs/contributors)
40
+ [![PRs](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/justin13601/ACES/pulls)
41
+ [![license](https://img.shields.io/badge/License-MIT-green.svg?labelColor=gray)](https://github.com/justin13601/ACES#license)
42
+
43
+ ## Background
44
+
45
+ EventStreamGPT (ESGPT) is a library that streamlines the development of generative, pre-trained transformers (i.e., foundation models) over event stream datasets, such as Electronic Health Records (EHR). ESGPT is designed to extract, preprocess, and manage these datasets efficiently, providing a Huggingface-compatible modeling API and introducing critical capabilities for representing complex intra-event causal dependencies and measuring zero-shot performance. For more detailed information, please refer to the ESGPT GitHub repository: [ESGPT GitHub Repo](https://github.com/esgpt).
46
+
47
+ A feature of ESGPT is the ability to query EHR datasets for valid subjects, guided by various constraints and requirements defined in a YAML configuration file. This streamlines the process of extracting task-specific cohorts from large time-series datasets, offering a powerful and user-friendly solution to researchers and developers. The use of a human-readable YAML configuration file also eliminates the need for users to be proficient in complex dataframe querying, making the querying process accessible to a broader audience.
48
+
49
+ There are diverse applications in healthcare and beyond. For instance, researchers can effortlessly define subsets of EHR datasets for training of foundational models. Retrospective analyses can also become more accessible to clinicians as it enables the extraction of tailored cohorts for studying specific medical conditions or population demographics.
50
+
51
+ This README provides an overview of this feature, including a description of the YAML configuration file's fields (see `sample_config.yaml`), an outline of the algorithm, and instructions for use.
52
+
53
+ Please also refer to the [documentation](https://eventstreamaces.readthedocs.io/en/latest/) for more information.
54
+
55
+ ## Dependencies
56
+
57
+ - polars
58
+ - bigtree
59
+ - ruamel.yaml
60
+
61
+ ## Installation
62
+
63
+ 1. Install ACES:
64
+
65
+ ```bash
66
+ pip install es-aces
67
+ ```
68
+
69
+ 2. If using the ESGPT data standard, install ESGPT (https://github.com/mmcdermott/EventStreamGPT):
70
+
71
+ Clone EventStreamGPT:
72
+
73
+ ```bash
74
+ git clone https://github.com/mmcdermott/EventStreamGPT.git
75
+ ```
76
+
77
+ Install package with dependencies from the root directory of the cloned repo:
78
+
79
+ ```bash
80
+ pip install -e .
81
+ ```
82
+
83
+ ## Instructions for Use
84
+
85
+ 1. **Prepare the YAML Configuration File**: Define your predicates and windows according to your research needs. Please see below for details regarding the configuration language.
86
+ 2. **Format Dataset into ESGPT Format**: Please follow instructions in the EventStreamGPT repo to build your dataset for ESGPT.
87
+ 3. **Load ACES**: Set-up and import ACES into your environment.
88
+
89
+ ```python
90
+ from aces import config, predicates, query
91
+ ```
92
+
93
+ 4. **Run the Query**: Use ACES with your YAML file to query a ESGPT dataset.
94
+
95
+ ```python
96
+ df_result = main.query_task(
97
+ cfg_path="/path/to/config.yaml", data="/path/to/folder/of/ESGPT/dataset/"
98
+ )
99
+ ```
100
+
101
+ 5. **Results**: The output will be a dataframe of subjects who satisfy the conditions defined in your YAML file. Timestamps for an edge of each window specified in the YAML, as well as predicate counts for each window, are also provided.
102
+
103
+ ## YAML Configuration File
104
+
105
+ The YAML configuration file allows users to define specific predicates and windows to query the ESD. Below is a description of each field:
106
+
107
+ ### Predicates
108
+
109
+ Predicates describe the event at a timestamp. Predicate columns begin with `is_` and are initialized as binary counts for each row of your ESD. Here is an example .csv file with predicate columns generated.
110
+
111
+ ```
112
+ subject_id,timestamp,event_type,dx,lab_test,lab_value,is_death,is_admission,is_discharge,is_covid,is_death_or_discharge,is_any
113
+ 1,12/1/1989 12:03,ADMISSION,,,,0,1,0,0,0,1
114
+ 1,12/1/1989 13:14,LAB,,SpO2,99,0,0,0,0,0,1
115
+ 1,12/1/1989 15:17,LAB,,SpO2,98,0,0,0,0,0,1
116
+ 1,12/1/1989 16:17,LAB,,SpO2,99,0,0,0,0,0,1
117
+ 1,12/1/1989 20:17,LAB,,SpO2,98,0,0,0,0,0,1
118
+ 1,12/2/1989 3:00,LAB,,SpO2,99,0,0,0,0,0,1
119
+ 1,12/2/1989 9:00,DIAGNOSIS,FLU,,,0,0,0,0,0,1
120
+ 1,12/2/1989 15:00,DISCHARGE,,,,0,0,1,0,1,1
121
+ ```
122
+
123
+ There are two types of predicates that can be defined in the configuration file. They can represent explicit ESD events and be defined by (`column`, `value`) pairs:
124
+
125
+ - `column`: Specifies the column in the dataset to apply the predicate. Must be a string matching an ESD column name.
126
+ - `value`: The value to match in the specified `column`.
127
+
128
+ OR, they can combine existing predicates using `ANY` or `ALL` keywords in the (`type`, `predicates`) pairs:
129
+
130
+ - `type`: Must be `ANY` or `ALL`.
131
+ - `predicates`: Must be list of existing predicate names defined using the above configuration.
132
+
133
+ ### Windows
134
+
135
+ Windows can be of two types. It can be a temporally-bound window defined by a `duration` and one of `start`/`end`. It can also be an event-bound window defined by a `start` and an `end`.
136
+
137
+ - `start`: Must be a string matching a predicate name or containing a window name to express window relationship.
138
+ - `duration`: Must be a positive or negative time period expressed as a string (ie. 2 days, -365 days, 12 hours, 30 minutes, 60 seconds).
139
+ - `offset`: Not yet available.
140
+ - `end`: Must be a string matching a predicate name or containing a window name to express window relationship.
141
+ - `excludes`: Listed `predicate` fields matching a predicate name. Used to exclude a predicate in the window.
142
+ - `includes`: Listed `predicate` fields matching a predicate name. Used to include a predicate in the window, with `min` and `max` specifying the constraints for occurrences (`None` is set where `min`/`max` is left blank).
143
+ - `st_inclusive`, `end_inclusive`: Boolean flags to indicate if events at the start and end of the window timestamps are included in the defined window.
144
+ - `label`: Must be a string matching a predicate name.
145
+
146
+ Each window uses these fields to define specific time frames and criteria within the dataset.
147
+
148
+ A sample YAML configuration file is provided in `sample_config.yaml`.
149
+
150
+ ## Recursive Algorithm Description
151
+
152
+ A tree structure is constructed based on the windows defined in the configuration file. This tree represents the hierarchical relationship between different time windows, where each node represents a window with its specific constraints. A set of base functions are required for the algorithm:
153
+
154
+ - `summarize_temporal_window()` creates a summary of predicate counts within a specified temporally-bound window.
155
+
156
+ - `summarize_event_bound_window()` creates a summary of predicate counts within a specified event-bound window.
157
+
158
+ - `summarize_window()` combines the functionalities of the above two functions.
159
+
160
+ - `check_constraints()` checks if the predicate counts in a window satisfy the inclusion and exclusion constraints of the window.
161
+
162
+ `query_subtree()` is recursively called to query each subtree in the tree structure in a depth-first manner. The function first summarizes the temporal- or event-bound window defined at each node by calling `summarize_window()`. Then, the returned summaries are filtered accordingly by `check_constraints()`. The resulting valid rows from each recursed node is then merged to form the final result.
163
+
164
+ ## Acknowledgements
165
+
166
+ **Matthew McDermott**, PhD | *Harvard Medical School*
167
+
168
+ For any questions, enhancements, or issues, please file a GitHub issue. For inquiries regarding EventStreamGPT, please refer to the ESGPT repository. Contributions are welcome via pull requests.
@@ -0,0 +1,138 @@
1
+ # Event Stream Automatic Cohort Extraction System (ACES)
2
+
3
+ [![python](https://img.shields.io/badge/-Python_3.10-blue?logo=python&logoColor=white)](https://github.com/pre-commit/pre-commit)
4
+ [![hydra](https://img.shields.io/badge/Config-Hydra_1.3-89b8cd)](https://hydra.cc/)
5
+ [![codecov](https://codecov.io/gh/justin13601/ACES/graph/badge.svg?token=6EA84VFXOV)](https://codecov.io/gh/justin13601/ACES)
6
+ [![tests](https://github.com/justin13601/ACES/actions/workflows/tests.yml/badge.svg)](https://github.com/justin13601/ACES/actions/workflows/test.yml)
7
+ [![code-quality](https://github.com/justin13601/ACES/actions/workflows/code-quality-master.yaml/badge.svg)](https://github.com/justin13601/ACES/actions/workflows/code-quality-master.yaml)
8
+ [![Documentation Status](https://readthedocs.org/projects/eventstreamaces/badge/?version=latest)](https://eventstreamaces.readthedocs.io/en/latest/?badge=latest)
9
+ [![contributors](https://img.shields.io/github/contributors/justin13601/ACES.svg)](https://github.com/justin13601/ACES/graphs/contributors)
10
+ [![PRs](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/justin13601/ACES/pulls)
11
+ [![license](https://img.shields.io/badge/License-MIT-green.svg?labelColor=gray)](https://github.com/justin13601/ACES#license)
12
+
13
+ ## Background
14
+
15
+ EventStreamGPT (ESGPT) is a library that streamlines the development of generative, pre-trained transformers (i.e., foundation models) over event stream datasets, such as Electronic Health Records (EHR). ESGPT is designed to extract, preprocess, and manage these datasets efficiently, providing a Huggingface-compatible modeling API and introducing critical capabilities for representing complex intra-event causal dependencies and measuring zero-shot performance. For more detailed information, please refer to the ESGPT GitHub repository: [ESGPT GitHub Repo](https://github.com/esgpt).
16
+
17
+ A feature of ESGPT is the ability to query EHR datasets for valid subjects, guided by various constraints and requirements defined in a YAML configuration file. This streamlines the process of extracting task-specific cohorts from large time-series datasets, offering a powerful and user-friendly solution to researchers and developers. The use of a human-readable YAML configuration file also eliminates the need for users to be proficient in complex dataframe querying, making the querying process accessible to a broader audience.
18
+
19
+ There are diverse applications in healthcare and beyond. For instance, researchers can effortlessly define subsets of EHR datasets for training of foundational models. Retrospective analyses can also become more accessible to clinicians as it enables the extraction of tailored cohorts for studying specific medical conditions or population demographics.
20
+
21
+ This README provides an overview of this feature, including a description of the YAML configuration file's fields (see `sample_config.yaml`), an outline of the algorithm, and instructions for use.
22
+
23
+ Please also refer to the [documentation](https://eventstreamaces.readthedocs.io/en/latest/) for more information.
24
+
25
+ ## Dependencies
26
+
27
+ - polars
28
+ - bigtree
29
+ - ruamel.yaml
30
+
31
+ ## Installation
32
+
33
+ 1. Install ACES:
34
+
35
+ ```bash
36
+ pip install es-aces
37
+ ```
38
+
39
+ 2. If using the ESGPT data standard, install ESGPT (https://github.com/mmcdermott/EventStreamGPT):
40
+
41
+ Clone EventStreamGPT:
42
+
43
+ ```bash
44
+ git clone https://github.com/mmcdermott/EventStreamGPT.git
45
+ ```
46
+
47
+ Install package with dependencies from the root directory of the cloned repo:
48
+
49
+ ```bash
50
+ pip install -e .
51
+ ```
52
+
53
+ ## Instructions for Use
54
+
55
+ 1. **Prepare the YAML Configuration File**: Define your predicates and windows according to your research needs. Please see below for details regarding the configuration language.
56
+ 2. **Format Dataset into ESGPT Format**: Please follow instructions in the EventStreamGPT repo to build your dataset for ESGPT.
57
+ 3. **Load ACES**: Set-up and import ACES into your environment.
58
+
59
+ ```python
60
+ from aces import config, predicates, query
61
+ ```
62
+
63
+ 4. **Run the Query**: Use ACES with your YAML file to query a ESGPT dataset.
64
+
65
+ ```python
66
+ df_result = main.query_task(
67
+ cfg_path="/path/to/config.yaml", data="/path/to/folder/of/ESGPT/dataset/"
68
+ )
69
+ ```
70
+
71
+ 5. **Results**: The output will be a dataframe of subjects who satisfy the conditions defined in your YAML file. Timestamps for an edge of each window specified in the YAML, as well as predicate counts for each window, are also provided.
72
+
73
+ ## YAML Configuration File
74
+
75
+ The YAML configuration file allows users to define specific predicates and windows to query the ESD. Below is a description of each field:
76
+
77
+ ### Predicates
78
+
79
+ Predicates describe the event at a timestamp. Predicate columns begin with `is_` and are initialized as binary counts for each row of your ESD. Here is an example .csv file with predicate columns generated.
80
+
81
+ ```
82
+ subject_id,timestamp,event_type,dx,lab_test,lab_value,is_death,is_admission,is_discharge,is_covid,is_death_or_discharge,is_any
83
+ 1,12/1/1989 12:03,ADMISSION,,,,0,1,0,0,0,1
84
+ 1,12/1/1989 13:14,LAB,,SpO2,99,0,0,0,0,0,1
85
+ 1,12/1/1989 15:17,LAB,,SpO2,98,0,0,0,0,0,1
86
+ 1,12/1/1989 16:17,LAB,,SpO2,99,0,0,0,0,0,1
87
+ 1,12/1/1989 20:17,LAB,,SpO2,98,0,0,0,0,0,1
88
+ 1,12/2/1989 3:00,LAB,,SpO2,99,0,0,0,0,0,1
89
+ 1,12/2/1989 9:00,DIAGNOSIS,FLU,,,0,0,0,0,0,1
90
+ 1,12/2/1989 15:00,DISCHARGE,,,,0,0,1,0,1,1
91
+ ```
92
+
93
+ There are two types of predicates that can be defined in the configuration file. They can represent explicit ESD events and be defined by (`column`, `value`) pairs:
94
+
95
+ - `column`: Specifies the column in the dataset to apply the predicate. Must be a string matching an ESD column name.
96
+ - `value`: The value to match in the specified `column`.
97
+
98
+ OR, they can combine existing predicates using `ANY` or `ALL` keywords in the (`type`, `predicates`) pairs:
99
+
100
+ - `type`: Must be `ANY` or `ALL`.
101
+ - `predicates`: Must be list of existing predicate names defined using the above configuration.
102
+
103
+ ### Windows
104
+
105
+ Windows can be of two types. It can be a temporally-bound window defined by a `duration` and one of `start`/`end`. It can also be an event-bound window defined by a `start` and an `end`.
106
+
107
+ - `start`: Must be a string matching a predicate name or containing a window name to express window relationship.
108
+ - `duration`: Must be a positive or negative time period expressed as a string (ie. 2 days, -365 days, 12 hours, 30 minutes, 60 seconds).
109
+ - `offset`: Not yet available.
110
+ - `end`: Must be a string matching a predicate name or containing a window name to express window relationship.
111
+ - `excludes`: Listed `predicate` fields matching a predicate name. Used to exclude a predicate in the window.
112
+ - `includes`: Listed `predicate` fields matching a predicate name. Used to include a predicate in the window, with `min` and `max` specifying the constraints for occurrences (`None` is set where `min`/`max` is left blank).
113
+ - `st_inclusive`, `end_inclusive`: Boolean flags to indicate if events at the start and end of the window timestamps are included in the defined window.
114
+ - `label`: Must be a string matching a predicate name.
115
+
116
+ Each window uses these fields to define specific time frames and criteria within the dataset.
117
+
118
+ A sample YAML configuration file is provided in `sample_config.yaml`.
119
+
120
+ ## Recursive Algorithm Description
121
+
122
+ A tree structure is constructed based on the windows defined in the configuration file. This tree represents the hierarchical relationship between different time windows, where each node represents a window with its specific constraints. A set of base functions are required for the algorithm:
123
+
124
+ - `summarize_temporal_window()` creates a summary of predicate counts within a specified temporally-bound window.
125
+
126
+ - `summarize_event_bound_window()` creates a summary of predicate counts within a specified event-bound window.
127
+
128
+ - `summarize_window()` combines the functionalities of the above two functions.
129
+
130
+ - `check_constraints()` checks if the predicate counts in a window satisfy the inclusion and exclusion constraints of the window.
131
+
132
+ `query_subtree()` is recursively called to query each subtree in the tree structure in a depth-first manner. The function first summarizes the temporal- or event-bound window defined at each node by calling `summarize_window()`. Then, the returned summaries are filtered accordingly by `check_constraints()`. The resulting valid rows from each recursed node is then merged to form the final result.
133
+
134
+ ## Acknowledgements
135
+
136
+ **Matthew McDermott**, PhD | *Harvard Medical School*
137
+
138
+ For any questions, enhancements, or issues, please file a GitHub issue. For inquiries regarding EventStreamGPT, please refer to the ESGPT repository. Contributions are welcome via pull requests.
@@ -0,0 +1,42 @@
1
+ [project]
2
+ name = "es-aces"
3
+ version = "0.2.0"
4
+ authors = [
5
+ { name="Justin Xu", email="justin13601@hotmail.com" },
6
+ { name="Matthew McDermott", email="mattmcdermott8@gmail.com" },
7
+ ]
8
+ description = "Event Stream Automatic Cohort Extraction System (ACES)"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ classifiers = [
12
+ "Programming Language :: Python :: 3",
13
+ "License :: OSI Approved :: MIT License",
14
+ "Operating System :: OS Independent",
15
+ ]
16
+ dependencies = [
17
+ "polars == 0.20.18",
18
+ "bigtree == 0.17.0",
19
+ "ruamel.yaml == 0.18.6",
20
+ "pandas == 2.2.2",
21
+ "loguru == 0.7.2",
22
+ "hydra-core == 1.3.2",
23
+ "pytimeparse == 1.1.8",
24
+ "networkx == 3.3",
25
+ ]
26
+
27
+ [project.scripts]
28
+ aces-cli = "aces.__main__:main"
29
+
30
+ [build-system]
31
+ requires = ["setuptools>=61.0", "wheel"]
32
+ build-backend = "setuptools.build_meta"
33
+
34
+ [project.optional-dependencies]
35
+ dev = [
36
+ "pre-commit", "pytest", "pytest-cov", "pytest-subtests", "rootutils"
37
+ ]
38
+ profiling = ["psutil"]
39
+
40
+ [project.urls]
41
+ Homepage = "https://github.com/justin13601/ACES"
42
+ Issues = "https://github.com/justin13601/ACES/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,76 @@
1
+ """Main script for end-to-end task querying."""
2
+
3
+ import os
4
+ from pathlib import Path
5
+
6
+ import hydra
7
+ import polars as pl
8
+ from loguru import logger
9
+ from omegaconf import DictConfig
10
+
11
+ from . import config, predicates, query
12
+
13
+
14
+ def load_using_directory(cfg: config.TaskExtractorConfig, path: str | Path) -> pl.DataFrame:
15
+ # currently only supports ESGPT dataset when loading from directory
16
+ return predicates.generate_predicates_df(cfg, path, standard="ESGPT")
17
+
18
+
19
+ def load_using_file(cfg: config.TaskExtractorConfig, path: str | Path) -> pl.DataFrame:
20
+ # .csv file
21
+ if path.suffix.lower() == ".csv":
22
+ return predicates.generate_predicates_df(cfg, path, standard="CSV")
23
+ # .parquet file (for MEDS)
24
+ elif path.suffix.lower() == ".parquet":
25
+ return predicates.generate_predicates_df(cfg, path, standard="MEDS")
26
+ else:
27
+ logger.error(f"Unsupported file type: {path.suffix}")
28
+ return
29
+
30
+
31
+ @hydra.main(version_base=None, config_path="", config_name="")
32
+ def main(cfg: DictConfig) -> None:
33
+ cfg = hydra.utils.instantiate(cfg, _convert_="all")
34
+
35
+ # Set output path
36
+ if "output_path" not in cfg or not cfg["output_path"]:
37
+ output_path = Path.cwd()
38
+ else:
39
+ output_path = Path(cfg["output_path"])
40
+
41
+ # load configuration
42
+ logger.info("Loading config...")
43
+ task_cfg_path = Path(cfg["config_path"])
44
+ task_cfg = config.TaskExtractorConfig.load(task_cfg_path)
45
+
46
+ # get predicates_df
47
+ logger.info("Loading data...")
48
+ data_path = Path(cfg["data_path"])
49
+ if not data_path.exists():
50
+ logger.error(f"{data_path} does not exist.")
51
+ return
52
+
53
+ if data_path.is_dir():
54
+ # load directory
55
+ logger.info("Directory provided, checking directory...")
56
+ predicates_df = load_using_directory(task_cfg, data_path)
57
+ else:
58
+ # load file
59
+ logger.info("File path provided, checking file...")
60
+ predicates_df = load_using_file(task_cfg, data_path)
61
+
62
+ # query results
63
+ result = query.query(task_cfg, predicates_df)
64
+
65
+ # save results
66
+ result = result.with_columns(
67
+ *[pl.col(col).struct.json_encode() for col in result.columns if "summary" in col]
68
+ ).write_csv(
69
+ os.path.join(output_path, "result.csv"),
70
+ include_header=True,
71
+ date_format="%m/%d/%Y %H:%M",
72
+ )
73
+
74
+
75
+ if __name__ == "__main__":
76
+ main()