-
Notifications
You must be signed in to change notification settings - Fork 0
WIP: ISARIC data schema integration #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
sr-murthy
wants to merge
16
commits into
main
Choose a base branch
from
integrate-isaric-schema
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Draft
Changes from all commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
591bbbe
feat: add ISARIC data schema template lib
sr-murthy 9301a5d
New ISARIC data schema lib + refreshed Sphinx docs
sr-murthy 363a7ea
test: add a basic unit test class for `isaric_data_schema`
sr-murthy ecdeb70
Integrate ISARIC transformations and data schema conversion pipeline …
sr-murthy afb04e9
docs: update contributing guide + RST fixes
sr-murthy 57b5ec5
docs: complete doctests for `utils`
sr-murthy c5e21f2
docs: a Pandas fix for a failing `utils` doctest
sr-murthy e6acf15
docs: simplify the doctest for `utils.clean_figure_table`
sr-murthy b360937
misc: add ISARIC transformations test module and a pytest conftest st…
sr-murthy 8448439
docs: further refine the contributing guide
sr-murthy de72d10
docs: remove TODO pages + update index
sr-murthy e56bc3e
Tweak test workflow from main rebase
sr-murthy 0d9a5f0
Various changes including use of fixtures and updating relevant tests…
sr-murthy 8f5ed04
Fix doctest execution and workflows
sr-murthy 62c3948
test: Further work on the ISARIC data schema pipeline + tests
sr-murthy 66d7bc3
fix: fix Hatch build target package paths in project TOML
sr-murthy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| ====================================== | ||
| ``isaricanalytics.isaric_data_schema`` | ||
| ====================================== | ||
|
|
||
| .. automodule:: isaricanalytics.isaric_data_schema | ||
| :members: | ||
| :special-members: |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| ========================================== | ||
| ``isaricanalytics.isaric_transformations`` | ||
| ========================================== | ||
|
|
||
| .. automodule:: isaricanalytics.isaric_transformations | ||
| :members: | ||
| :special-members: |
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| from __future__ import annotations | ||
|
|
||
| __all__ = [ | ||
| "transform_to_isaric_data_schema", | ||
| ] | ||
|
|
||
|
|
||
| # -- IMPORTS -- | ||
|
|
||
| # -- Standard libraries -- | ||
| import pathlib | ||
| import typing | ||
| import warnings as warnings_ | ||
|
|
||
| # -- 3rd party libraries -- | ||
| import adtl | ||
| import pandas as pd | ||
|
|
||
| # -- Internal ISARIC libraries -- | ||
| from bridge.arc.arc_api import ArcApiClient, ArcApiClientError | ||
| from bridge.arc.arc_core import get_arc | ||
|
|
||
| import isaricanalytics.isaric_transformations as tf | ||
|
|
||
|
|
||
| class IsaricDataSchemaTransformationException(Exception): ... | ||
|
sr-murthy marked this conversation as resolved.
Dismissed
|
||
|
|
||
|
|
||
| def _warn_on_non_arc_columns( | ||
| column_set: typing.Iterable, column_type: str, arc_version: str, stacklevel=2 | ||
| ) -> None: | ||
| """Warns on the transform function detecting non-ARC columns in the core or long schema tables.""" # noqa: E501 | ||
| columns_str = ", ".join(map(lambda s: f'"{s}"', sorted(column_set))) | ||
| msg = ( | ||
| f"\n\nThe following {column_type} table columns are not in ARC " | ||
| f"{arc_version}: {columns_str}\n\nPlease check these columns." | ||
| ) | ||
| warnings_.warn(msg, DeprecationWarning, stacklevel=stacklevel) | ||
|
|
||
|
|
||
| def transform_to_isaric_data_schema( | ||
| parser_file: str | pathlib.Path, | ||
| data_file: str | pathlib.Path, | ||
| arc_version: str | None = None, | ||
| ) -> dict[str, pd.DataFrame]: | ||
| """:py:class:`dict` : A dict of ISARIC schema-compliant short/core- and long-format datasets as Pandas dataframes. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| parser_file : str or pathlib.Path | ||
| The parser TOML file path. | ||
|
|
||
| data_file : str or pathlib.Path | ||
| The data file path. | ||
|
|
||
| arc_version : str or None, default=None | ||
| Optional ARC version string used to fetch the ARC data dictionary | ||
| associated with the ARC version; defaults to ``None``. | ||
|
|
||
| Returns | ||
| ------- | ||
| dict | ||
| A dict of two Pandas dataframes representing short- and long-format | ||
| ISARIC schema-compliant transforms of the original dataset. | ||
|
|
||
| Raises | ||
| ------ | ||
| IsaricDataSchemaTransformationException | ||
| In case of an ARC API client exception. | ||
| """ # noqa : E501 | ||
| # Call ADTL to parse the data and retrieve the core and long-format tables. | ||
| ids_tables = adtl.parse(parser_file, data_file, include_transform=tf.__file__) | ||
|
|
||
| # An ARC version is required to fetch the ARC data dictionary. If no ARC | ||
| # version is provided by the caller, fetch the latest directly from ARC @ | ||
| # GitHub - in case of an exception raise it. | ||
| if not arc_version: | ||
| try: | ||
| arc_version = ArcApiClient().get_arc_version_list()[0] | ||
| except (ArcApiClientError, IndexError) as e: | ||
| raise IsaricDataSchemaTransformationException( | ||
| f'Exception fetching ARC version "{arc_version}": ' | ||
| f"{e}.\n\n Please check that you have provided a valid " | ||
| "ARC version. If you have then there may be a network- " | ||
| "related error, so please retry after some time." | ||
| ) | ||
|
|
||
| # Fetch the ARC data dictionary associated with the ARC version - in case | ||
| # of an exception raise it. | ||
| try: | ||
| arc_dd = get_arc(arc_version)[0] | ||
| except (ArcApiClientError, IndexError) as e: | ||
| raise IsaricDataSchemaTransformationException( | ||
| "Exception fetching ARC data dictionary for ARC version " | ||
| f'"{arc_version}": {e}.\n\n Please check that you have provided a ' | ||
| "valid ARC version. If you have, then please retry after some " | ||
| "time." | ||
| ) | ||
|
|
||
| # Checking transformed columns in the core and long tables against ARC, and | ||
| # issuing warnings about any non-ARC columns in either. | ||
| non_arc_core_columns = set(ids_tables["core"].columns).difference( | ||
| arc_dd["Variable"] | ||
| ) | ||
| if non_arc_core_columns: | ||
| _warn_on_non_arc_columns( | ||
| non_arc_core_columns, "core", arc_version, stacklevel=2 | ||
| ) | ||
|
|
||
| non_arc_long_columns = set(ids_tables["long"].columns).difference( | ||
| arc_dd["Variable"] | ||
| ) | ||
| if non_arc_long_columns: | ||
| _warn_on_non_arc_columns( | ||
| non_arc_long_columns, "long", arc_version, stacklevel=2 | ||
| ) | ||
|
|
||
| return ids_tables | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| from __future__ import annotations | ||
|
|
||
| __all__ = [ | ||
| "MISSING_ATTRIBUTE_STATUS", | ||
| "attribute_status_fill", | ||
| "values_strip_missing", | ||
| ] | ||
|
|
||
|
|
||
| # -- IMPORTS -- | ||
|
|
||
| # -- Standard libraries -- | ||
| from enum import Enum | ||
|
|
||
| # -- 3rd party libraries -- | ||
|
|
||
| # -- Internal libraries -- | ||
|
|
||
|
|
||
| class MISSING_ATTRIBUTE_STATUS(Enum): | ||
| # Unknown | ||
| UNKNOWN = "UNK" | ||
|
|
||
| # No information | ||
| NO_INFORMATION = "NI" | ||
|
|
||
| # Not asked | ||
| NOT_ASKED = "NASK" | ||
|
|
||
| # Not applicable | ||
| NOT_APPLICABLE = "NA" | ||
|
|
||
|
|
||
| def attribute_status_fill(field: str) -> str | None: | ||
|
github-code-quality[bot] marked this conversation as resolved.
Fixed
sr-murthy marked this conversation as resolved.
Dismissed
|
||
| """:py:class:`str` or :py:class:`NoneType` : Infer attribute status if it is missing. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| field : str | ||
| Attribute status field. | ||
|
|
||
| Returns | ||
| ------- | ||
| str or None | ||
| The original status field if it is one of the values: | ||
|
|
||
| * ``'UNK'`` - unknown | ||
| * ``'NI'`` - no information | ||
| * ``'NASK'`` - not asked | ||
| * ``'NA'`` - not applicable | ||
|
|
||
| or ``'VAL'`` if it is non-null but different from the above, otherwise | ||
| ``None``. | ||
|
|
||
| Examples | ||
| -------- | ||
| >>> attribute_status_fill("UNK") | ||
| 'UNK' | ||
| >>> attribute_status_fill("NI") | ||
| 'NI' | ||
| >>> attribute_status_fill("NASK") | ||
| 'NASK' | ||
| >>> attribute_status_fill("NA") | ||
| 'NA' | ||
| >>> attribute_status_fill("XYZ") | ||
| 'VAL' | ||
| >>> attribute_status_fill(None) | ||
| >>> | ||
| """ # noqa : E501 | ||
| if field is None: | ||
| return None | ||
|
|
||
| match field: | ||
| case ( | ||
| MISSING_ATTRIBUTE_STATUS.UNKNOWN.value | ||
| | MISSING_ATTRIBUTE_STATUS.NO_INFORMATION.value | ||
| | MISSING_ATTRIBUTE_STATUS.NOT_ASKED.value | ||
| | MISSING_ATTRIBUTE_STATUS.NOT_APPLICABLE.value | ||
| ): | ||
| return field | ||
| case _: | ||
| return "VAL" | ||
|
|
||
|
|
||
| def values_strip_missing(field: str) -> str | None: | ||
|
github-code-quality[bot] marked this conversation as resolved.
Fixed
sr-murthy marked this conversation as resolved.
Dismissed
|
||
| """:py:class:`str` or :py:class:`NoneType` : Strip missing attribute status field. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| field : str | ||
| Attribute status field. | ||
|
|
||
| Returns | ||
| ------- | ||
| str or None | ||
| Null if it is one of the values: | ||
|
|
||
| * ``'UNK'`` - unknown | ||
| * ``'NI'`` - no information | ||
| * ``'NASK'`` - not asked | ||
| * ``'NA'`` - not applicable | ||
|
|
||
| and ``None`` otherwise. | ||
|
|
||
| Examples | ||
| -------- | ||
| >>> values_strip_missing("UNK") | ||
| >>> | ||
| >>> values_strip_missing("NI") | ||
| >>> | ||
| >>> values_strip_missing("NASK") | ||
| >>> | ||
| >>> values_strip_missing("NA") | ||
| >>> | ||
| >>> values_strip_missing("XYZ") | ||
| 'XYZ' | ||
| >>> values_strip_missing(None) | ||
| >>> | ||
| """ # noqa : E501 | ||
|
|
||
| match field: | ||
| case ( | ||
| MISSING_ATTRIBUTE_STATUS.UNKNOWN.value | ||
| | MISSING_ATTRIBUTE_STATUS.NO_INFORMATION.value | ||
| | MISSING_ATTRIBUTE_STATUS.NOT_ASKED.value | ||
| | MISSING_ATTRIBUTE_STATUS.NOT_APPLICABLE.value | ||
| ): | ||
| return None | ||
| case _: | ||
| return field | ||
|
|
||
|
|
||
| if __name__ == "__main__": # pragma: no cover | ||
| # Doctest the module from the project root using | ||
| # | ||
| # python3 -m doctest -v src/isaricanalytics/isaric_transformations.py # noqa : E501 | ||
| # | ||
| import doctest | ||
|
|
||
| doctest.testmod() | ||
File renamed without changes.
File renamed without changes.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.