From 596aa15660cc496edf02d1b5924333cb4cdc1ecc Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Mon, 18 Nov 2024 15:45:28 -0500 Subject: [PATCH 01/18] B2AI-538 --- src/dashboard.py | 2 ++ src/tabs/overview.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/tabs/overview.py diff --git a/src/dashboard.py b/src/dashboard.py index 46b5ac2..411b5cb 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -3,6 +3,7 @@ import streamlit as st +from tabs.overview import overview_page from tabs.about import about_page from tabs.healthsheet import healthsheet_page from tabs.study_dashboard import study_dashboard_page @@ -57,6 +58,7 @@ def main(): # dataset_uses_page() is defined in tabs/dataset_uses.py tab_functions = { + "Overview": overview_page, "About": about_page, "Healthsheet": healthsheet_page, "Study Dashboard": study_dashboard_page, diff --git a/src/tabs/overview.py b/src/tabs/overview.py new file mode 100644 index 0000000..ae4c459 --- /dev/null +++ b/src/tabs/overview.py @@ -0,0 +1,28 @@ +import streamlit as st +from tabs.utils import coming_soon_message + +def overview_page(tab_name): + # coming_soon_message(tab_name) + st.markdown( + """ + Training opportunities for using dataset: [https://www.b2aivoicescholars.org/](https://www.b2aivoicescholars.org/) + + Bridge2AI-Voice is a Precision Public Health grand challenge project funded by the NIH Common Fund Bridge2AI Program. Bridge2AI-Voice seeks to create a flagship, standardized, and ethically sourced dataset of 10,000 voices linked to health information to fuel research and discovery in voice biomarkers. + + Our group aims to promote integration of voice as a biomarker of health in clinical care. To do so, we will generate a large multi-institutional, ethically sourced, and diverse voice dataset linked to multimodal health biomarkers to fuel voice AI research. Data collection is performed via a novel app (The Bridge2AI-Voice App) available as smartphone application linked to electronic health records (EHR). The app collected breathing sounds, voice, speech and linguistic tasks but also a considerable amount of health information through surveys and validated questionnaires. Other multimodal data collected includes imaging, genomics and respiratory function tests amongst others. The consortium is also addressing the growing ethical, legal, and social challenges surrounding voice AI, including risks of voice re-identification, vulnerabilities like voice AI hacking, concerns around voice data sharing and privacy, and the influence of gender and racial diversity on the development and application of these technologies. + + Our developed best ethical practices through ethical inquiry have guided the development of voice collection protocol as well as data dissemination practices. + + As voice is increasingly being recognized as a biomarker of health by the tech world and voice AI is gaining attention from multi-nationals such as Google, Amazon, Mozilla and Apple amongst others, many important issues related to patient privacy protection, ethical and fair representation of population, and clinical accuracy are arising. As a multidisciplinary group of academic experts, we aim to influence and guide the world of voice AI by ensuring patient protection through ethical and fairness principles and create safe innovative infrastructures to disseminate ethically sourced data for the future generations of voice AI researchers. + + Based on the existing literature and ongoing research in different fields of voice research, our group has identified 5 disease cohort categories for which voice changes have been associated to specific diseases with well-recognized unmet needs and for which our data acquisition efforts are focused: + - Voice Disorders + - Neurological and Neurodegenerative Disorders + - Mood and Psychiatric Disorders + - Respiratory disorders + - Pediatric Voice and Speech Disorders + + Please Note: This V1.0 of the public data release does not contain pediatric data. It also does not contain an equal distribution of these categories of diseases. Further releases will contain additional data. + + """ + ) \ No newline at end of file From 52807893a49b0797bbf194cc131cadca988c1e43 Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Mon, 18 Nov 2024 15:47:09 -0500 Subject: [PATCH 02/18] B2AI-538 --- README.md | 2 +- src/dashboard.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c1f56c0..340383e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Docs for the Bridge2AI Voice Project. -[![Github](https://img.shields.io/badge/github-1.1.0-green?style=flat&logo=github)](https://github.com/eipm/bridge2ai-docs) [![Python 3.12.0](https://img.shields.io/badge/python-3.12.0-blue.svg)](https://www.python.org/downloads/release/python-3120/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![DOI](https://zenodo.org/badge/860006845.svg)](https://zenodo.org/doi/10.5281/zenodo.13834653) +[![Github](https://img.shields.io/badge/github-1.2.0-green?style=flat&logo=github)](https://github.com/eipm/bridge2ai-docs) [![Python 3.12.0](https://img.shields.io/badge/python-3.12.0-blue.svg)](https://www.python.org/downloadxs/release/python-3120/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![DOI](https://zenodo.org/badge/860006845.svg)](https://zenodo.org/doi/10.5281/zenodo.13834653) ## 🤝 License diff --git a/src/dashboard.py b/src/dashboard.py index 411b5cb..c04dfa0 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -44,7 +44,7 @@ def create_tabs(tabs_func): def main(): # Current version of the app - version = "1.1.0" + version = "1.2.0" # Map tab names to functions # In this dictionary, the key is the tab name and the value is the function that will be called when the tab is selected # The function is defined in the respective file From ea64975ad65510e49ad9b84bb617a4076d4a8f15 Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Mon, 18 Nov 2024 16:13:59 -0500 Subject: [PATCH 03/18] updated pages --- src/dashboard.py | 35 ++++++++++--------- src/tabs/{about.py => ai_readiness.py} | 2 +- ...{dataset_uses.py => collection_methods.py} | 3 +- ...dataset_metadata.py => data_governance.py} | 3 +- src/tabs/data_pre_processing.py | 5 +++ src/tabs/dataset_quality_dashboard.py | 6 ---- 6 files changed, 27 insertions(+), 27 deletions(-) rename src/tabs/{about.py => ai_readiness.py} (75%) rename src/tabs/{dataset_uses.py => collection_methods.py} (55%) rename src/tabs/{dataset_metadata.py => data_governance.py} (53%) create mode 100644 src/tabs/data_pre_processing.py delete mode 100644 src/tabs/dataset_quality_dashboard.py diff --git a/src/dashboard.py b/src/dashboard.py index c04dfa0..fd10dce 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -4,14 +4,15 @@ import streamlit as st from tabs.overview import overview_page -from tabs.about import about_page -from tabs.healthsheet import healthsheet_page +from tabs.collection_methods import collection_methods_page +from tabs.data_governance import data_governance_page from tabs.study_dashboard import study_dashboard_page from tabs.study_metadata import study_metadata_page -from tabs.dataset_metadata import dataset_metadata_page +from tabs.healthsheet import healthsheet_page +from tabs.data_pre_processing import data_pre_processing_page +from tabs.ai_readiness import ai_readiness_page + from tabs.dataset_structure_preview import dataset_structure_preview_page -from tabs.dataset_quality_dashboard import dataset_quality_dashboard_page -from tabs.dataset_uses import dataset_uses_page def config_page(version): st.set_page_config( @@ -48,25 +49,27 @@ def main(): # Map tab names to functions # In this dictionary, the key is the tab name and the value is the function that will be called when the tab is selected # The function is defined in the respective file - # about_page() is defined in tabs/about.py - # healthsheet_page() is defined in tabs/healthsheet.py + # overview_page() is defined in tabs/overview.py + # collections_methods_page() is defined in tabs/collections_methods.py + # data_governance_page() is defined in tabs/data_governance.py # study_dashboard_page() is defined in tabs/study_dashboard.py # study_metadata_page() is defined in tabs/study_metadata.py - # dataset_metadata_page() is defined in tabs/dataset_metadata.py + # healthsheet_page() is defined in tabs/healthsheet.py + # data_pre_processing_page() is defined in tabs/data_pre_processing.py + # ai_readiness_page() is defined in tabs/ai_readiness.py + # dataset_structure_preview_page() is defined in tabs/dataset_structure_preview.py - # dataset_quality_dashboard_page() is defined in tabs/dataset_quality_dashboard.py - # dataset_uses_page() is defined in tabs/dataset_uses.py tab_functions = { "Overview": overview_page, - "About": about_page, - "Healthsheet": healthsheet_page, + "Collection Methods": collection_methods_page, + "Data Governance": data_governance_page, "Study Dashboard": study_dashboard_page, "Study Metadata": study_metadata_page, - "Dataset Metadata": dataset_metadata_page, - "Dataset Structure Preview": dataset_structure_preview_page, - "Dataset Quality Dashboard": dataset_quality_dashboard_page, - "Dataset Uses": dataset_uses_page + "Healthsheet": healthsheet_page, + "Data Pre-Processing": data_pre_processing_page, + "AI-Readiness": ai_readiness_page, + "Dataset Structure Preview": dataset_structure_preview_page } # Set page configuration diff --git a/src/tabs/about.py b/src/tabs/ai_readiness.py similarity index 75% rename from src/tabs/about.py rename to src/tabs/ai_readiness.py index 34f0928..b5d93aa 100644 --- a/src/tabs/about.py +++ b/src/tabs/ai_readiness.py @@ -1,5 +1,5 @@ import streamlit as st from tabs.utils import coming_soon_message -def about_page(tab_name): +def ai_readiness_page(tab_name): coming_soon_message(tab_name) \ No newline at end of file diff --git a/src/tabs/dataset_uses.py b/src/tabs/collection_methods.py similarity index 55% rename from src/tabs/dataset_uses.py rename to src/tabs/collection_methods.py index 2a37708..0e844c7 100644 --- a/src/tabs/dataset_uses.py +++ b/src/tabs/collection_methods.py @@ -1,6 +1,5 @@ import streamlit as st from tabs.utils import coming_soon_message -# Define the content of the Dataset Uses page -def dataset_uses_page(tab_name): +def collection_methods_page(tab_name): coming_soon_message(tab_name) \ No newline at end of file diff --git a/src/tabs/dataset_metadata.py b/src/tabs/data_governance.py similarity index 53% rename from src/tabs/dataset_metadata.py rename to src/tabs/data_governance.py index 3386039..aa2d7f0 100644 --- a/src/tabs/dataset_metadata.py +++ b/src/tabs/data_governance.py @@ -1,6 +1,5 @@ import streamlit as st from tabs.utils import coming_soon_message -# Define the content of the Dataset Metadata page -def dataset_metadata_page(tab_name): +def data_governance_page(tab_name): coming_soon_message(tab_name) \ No newline at end of file diff --git a/src/tabs/data_pre_processing.py b/src/tabs/data_pre_processing.py new file mode 100644 index 0000000..14d17fa --- /dev/null +++ b/src/tabs/data_pre_processing.py @@ -0,0 +1,5 @@ +import streamlit as st +from tabs.utils import coming_soon_message + +def data_pre_processing_page(tab_name): + coming_soon_message(tab_name) \ No newline at end of file diff --git a/src/tabs/dataset_quality_dashboard.py b/src/tabs/dataset_quality_dashboard.py deleted file mode 100644 index f4d7e71..0000000 --- a/src/tabs/dataset_quality_dashboard.py +++ /dev/null @@ -1,6 +0,0 @@ -import streamlit as st -from tabs.utils import coming_soon_message - -# Define the content of the Dataset Quality Dashboard page -def dataset_quality_dashboard_page(tab_name): - coming_soon_message(tab_name) \ No newline at end of file From 82f94ac3553d88dec6f77b75f47c87f5fa696d95 Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Mon, 18 Nov 2024 17:06:44 -0500 Subject: [PATCH 04/18] updated overview --- src/tabs/overview.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tabs/overview.py b/src/tabs/overview.py index ae4c459..bda563f 100644 --- a/src/tabs/overview.py +++ b/src/tabs/overview.py @@ -2,7 +2,6 @@ from tabs.utils import coming_soon_message def overview_page(tab_name): - # coming_soon_message(tab_name) st.markdown( """ Training opportunities for using dataset: [https://www.b2aivoicescholars.org/](https://www.b2aivoicescholars.org/) From 654764d4ccb15ef7c09ff05c5f8b500b38817dc1 Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Tue, 19 Nov 2024 16:52:03 -0500 Subject: [PATCH 05/18] B2AI-544 --- images/ai-readiness-figure-1.png | Bin 0 -> 71874 bytes src/tabs/ai_readiness.py | 23 +++++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 images/ai-readiness-figure-1.png diff --git a/images/ai-readiness-figure-1.png b/images/ai-readiness-figure-1.png new file mode 100644 index 0000000000000000000000000000000000000000..def89d62f47f39d37509036ccf40a71f1e4d1a77 GIT binary patch literal 71874 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 literal 0 HcmV?d00001 diff --git a/src/tabs/ai_readiness.py b/src/tabs/ai_readiness.py index b5d93aa..13218e9 100644 --- a/src/tabs/ai_readiness.py +++ b/src/tabs/ai_readiness.py @@ -1,5 +1,24 @@ import streamlit as st -from tabs.utils import coming_soon_message +# from tabs.utils import coming_soon_message + +import pandas as pd +import numpy as np def ai_readiness_page(tab_name): - coming_soon_message(tab_name) \ No newline at end of file + st.markdown( + """ + For detailed descriptions of each criteria, please read: [https://www.biorxiv.org/content/10.1101/2024.10.23.619844v2](https://www.biorxiv.org/content/10.1101/2024.10.23.619844v2) + """ + ) + + # Add Figure + image_path = "images/ai-readiness-figure-1.png" + st.image(image_path, use_column_width=True) + + # Add Table + + # df = pd.DataFrame( + # np.random.randn(10, 5), columns=("col %d" % i for i in range(5)) + # ) + + # st.table(df) \ No newline at end of file From dbe76007e0eae2a8bdb929bcb997a9889c13f5dc Mon Sep 17 00:00:00 2001 From: Jeff Tang <47529643+jmtang2018@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:18:16 -0500 Subject: [PATCH 06/18] added tables to docs --- css/dashboard.css | 2 +- src/tabs/ai_readiness.py | 1102 ++++++++++++++++- src/tabs/tables/Acoustic_Tasks_Protocol.csv | 23 + ...se_cohort_inclusion_exclusion_criteria.csv | 31 + src/tabs/tables/Validated_Questionnaires.csv | 13 + src/tabs/utils.py | 50 +- 6 files changed, 1216 insertions(+), 5 deletions(-) create mode 100644 src/tabs/tables/Acoustic_Tasks_Protocol.csv create mode 100644 src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv create mode 100644 src/tabs/tables/Validated_Questionnaires.csv diff --git a/css/dashboard.css b/css/dashboard.css index 8ff32b0..ed10170 100644 --- a/css/dashboard.css +++ b/css/dashboard.css @@ -55,7 +55,7 @@ footer { font-size: smaller; } -@media screen and (max-width: 1278px) { +@media screen and (max-width: 1400px) { .stTabs [data-baseweb="tab-list"] { padding-bottom: 25px; } diff --git a/src/tabs/ai_readiness.py b/src/tabs/ai_readiness.py index 13218e9..3eb9c1d 100644 --- a/src/tabs/ai_readiness.py +++ b/src/tabs/ai_readiness.py @@ -1,5 +1,7 @@ import streamlit as st # from tabs.utils import coming_soon_message +from tabs.utils import create_html_table +from tabs.utils import create_html_table_span_col_row import pandas as pd import numpy as np @@ -10,15 +12,1109 @@ def ai_readiness_page(tab_name): For detailed descriptions of each criteria, please read: [https://www.biorxiv.org/content/10.1101/2024.10.23.619844v2](https://www.biorxiv.org/content/10.1101/2024.10.23.619844v2) """ ) - # Add Figure image_path = "images/ai-readiness-figure-1.png" - st.image(image_path, use_column_width=True) + lt, cent, rt = st.columns([1,3,1], gap="small") + with cent: + st.image(image_path, use_container_width=True) + # Add Table + st.markdown( + """ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Precision Public Health (Voice) - Current Rating +
CriterionCriterion met? (Y=1; N=0)Total Score for Criterion (%)
FAIRness (0)Findable (0.a)1100
Accessible (0.b)1
Interoperable (0.c)1
Reusable (0.d)1
Provenance (1)Transparent (1.a)1100
Traceable (1.b)1
Interpretable (1.c)1
Key actors identified (1.d)1
Characterization (2)Semantics (2.a)180
Statistics (2.b)1
Standards (2.c)1
Potential Sources of Bias (2.d)1
Data Quality (2.e)0
Pre-model explainability (3)Data documentation templates (3.a)1100
Fit for purpose (3.c)1
Verifiable (3.d)1
Ethics (4)Ethically acquired (4.a)1100
Ethically managed (4.b)1
Ethically disseminated (4.c)1
Secure (4.d)1
Sustainability (5)Persistent (5.a)150
Domain-appropriate (5.b)0
Well-governed (5.c)1
Associated (5.d)0
Computability (6)Standardized (6.a)175
Computational Accessibility (6.b)1
Portable (6.c)1
Contextualized (6.d)0
+ """, + unsafe_allow_html=True + ) + # st.markdown( + # """ + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + #
+ #

 

+ #
+ #

 

+ #
+ #

 

+ #
+ #

 

+ #
+ #

Precision Public Health (Voice) - Current Rating

+ #
+ #

Criterion

+ #
+ #

Criterion met? (Y=1; N=0)

+ #
+ #

Total Score for Criterion (%)

+ #
+ #

FAIRness (0)

+ #
+ #

Findable + # (0.a)

+ #
+ #

1

+ #
+ #

100

+ #
+ #

Accessible + # (0.b)

+ #
+ #

1

+ #
+ #

Interoperable + # (0.c)

+ #
+ #

1

+ #
+ #

Reusable + # (0.d)

+ #
+ #

1

+ #
+ #

Provenance + # (1)

+ #
+ #

Transparent + # (1.a)

+ #
+ #

1

+ #
+ #

100

+ #
+ #

Traceable + # (1.b)

+ #
+ #

1

+ #
+ #

Interpretable + # (1.c)

+ #
+ #

1

+ #
+ #

Key actors identified + # (1.d)

+ #
+ #

1

+ #
+ #

Characterization + # (2)

+ #
+ #

Semantics + # (2.a)

+ #
+ #

1

+ #
+ #

80

+ #
+ #

Statistics + # (2.b)

+ #
+ #

1

+ #
+ #

Standards + # (2.c)

+ #
+ #

1

+ #
+ #

Potential + # Sources of Bias (2.d)

+ #
+ #

1

+ #
+ #

Data + # Quality (2.e)

+ #
+ #

0

+ #
+ #

Pre-model + # explainability (3)

+ #
+ #

Data + # documentation templates (3.a)

+ #
+ #

1

+ #
+ #

100

+ #
+ #

Fit for purpose + # (3.c)

+ #
+ #

1

+ #
+ #

Verifiable + # (3.d)

+ #
+ #

1

+ #
+ #

Ethics (4)

+ #
+ #

Ethically + # acquired (4.a)

+ #
+ #

1

+ #
+ #

100

+ #
+ #

Ethically + # managed (4.b)

+ #
+ #

1

+ #
+ #

Ethically + # disseminated (4.c)

+ #
+ #

1

+ #
+ #

Secure + # (4.d)

+ #
+ #

1

+ #
+ #

Sustainability + # (5)

+ #
+ #

Persistent + # (5.a)

+ #
+ #

1

+ #
+ #

50

+ #
+ #

Domain-appropriate + # (5.b)

+ #
+ #

0

+ #
+ #

Well-governed + # (5.c)

+ #
+ #

1

+ #
+ #

Associated + # (5.d)

+ #
+ #

0

+ #
+ #

Computability + # (6)

+ #
+ #

Standardized + # (6.a)

+ #
+ #

1

+ #
+ #

75

+ #
+ #

Computational + # Accessibility (6.b)

+ #
+ #

1

+ #
+ #

Portable + # (6.c)

+ #
+ #

1

+ #
+ #

Contextualized + # (6.d)

+ #
+ #

0

+ #
+ # """, + # unsafe_allow_html=True + # ) # df = pd.DataFrame( # np.random.randn(10, 5), columns=("col %d" % i for i in range(5)) # ) - # st.table(df) \ No newline at end of file + # st.table(df) + + # MOVE TO "SECTION: Collection methods" + csv_file_path = "src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv" + caption = 'Table 1. Disease cohort inclusion/exclusion criteria and validation methods' + create_html_table(csv_file_path, caption) + + csv_file_path = "src/tabs/tables/Acoustic_Tasks_Protocol.csv" + caption = 'Table 2. Acoustic Tasks in Protocol' + create_html_table(csv_file_path, caption) + + csv_file_path = "src/tabs/tables/Validated_Questionnaires.csv" + caption = 'Table 3 Validated Questionnaires integrated into App' + create_html_table(csv_file_path, caption) + diff --git a/src/tabs/tables/Acoustic_Tasks_Protocol.csv b/src/tabs/tables/Acoustic_Tasks_Protocol.csv new file mode 100644 index 0000000..02c05e7 --- /dev/null +++ b/src/tabs/tables/Acoustic_Tasks_Protocol.csv @@ -0,0 +1,23 @@ +Name,Task,Description,Part +Non Voice/Non Speech,Respiration Part A,Breathing sounds,A +Non Voice/Non Speech,Cough part A,Voluntary Cough,A +Non Voice/Non Speech,Breath Sounds,Breathing sounds,Resp +Non Voice/Non Speech,Voluntary Cough,Voluntary Cough,Resp +Voice / Non Speech,Prolonged Vowel,vowel /e/,A +Voice / Non Speech,Maximum Phonation Time,vowel /e/,A +Voice / Non Speech,Glides,Lowest to Highest /e/,A +Voice / Non Speech,Loudness,/Hey/,A +Voice / Non Speech,Diadochokinesis,/pa/ta/ka/ /buttercup/,A +Speech,Rainbow Passage,validated passage,A +Speech,Caterpillar Passage,validated passage,Voice +Speech,Cape-V Sentences,validated sentences,Voice +Speech,Free Speech Part A,open questions,A +Speech,Picture Description,describing a picture,A +Speech,Free Speech Voice,open questions,Voice +Speech,Story Recall,speech after reading a story,A +Speech,Animal Fluency,name animals,Mood +Speech,Open Response Questions,open questions,Mood +Speech,Word-Color Stroop,color descriptions,Neuro +Speech,Productive Vocabulary,describing images,Neuro +Speech,Random Item generation,describing images,Neuro +Speech,Cinderella Story,story,Neuro diff --git a/src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv b/src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv new file mode 100644 index 0000000..1b4a86a --- /dev/null +++ b/src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv @@ -0,0 +1,31 @@ +Disease Cohort ,Diagnosis ,Inclusion Criteria ,Exclusion Criteria ,Gold Standard Validation Methods +Vocal Disorders Cohort ,Laryngeal Cancer ,"Active laryngeal cancer T1-T4 Biopsy proven (if no biopsy at time of collection and suspicion is very high, provider will have to go back to confirm in the clinical validation section after the biopsy is obtained) ",Previously treated laryngeal cancer with no evidence of disease on scope ,Laryngoscopy Images Stroboscopy Videos +Vocal Disorders Cohort ,Laryngitis ,Acute laryngitis Chronic laryngitis Bacterial laryngitis Fungal laryngitis Autoimmune laryngitis *need to have evidence of information of the vocal cords on laryngoscopy as well as dysphonia ,Subjective laryngitis without evidence on scope ,Laryngoscopy Images Stroboscopy Videos +Vocal Disorders Cohort ,Pre-cancerous lesions ,Keratosis Leukoplakia (note if with or without dysplasia) ,Low grade - ,Laryngoscopy Images Stroboscopy Videos +Vocal Disorders Cohort ,"Benign Lesions of the vocal cord (nodule, polyp, cyst) ",Vocal fold nodules Vocal fold polyp Vocal fold cyst Reinke's Edema Vocal fold ulcers Recurrent respiratory Papilloma Fibrous mass Rheumatoid nodules Recurrent Laryngeal Papilloma (RLP) ,Patient has received surgery for any condition and does not have evidence of pathology when scoped Immediate post op prior less than 30 days from laryngeal surgery ,Laryngoscopy Images Stroboscopy Videos +Vocal Disorders Cohort ,Muscle Tension Dysphonia (MTD) ,Laryngology & SLP diagnosis , ,Laryngoscopy Images Stroboscopy Videos +Vocal Disorders Cohort ,Spasmodic Dysphonia/Laryngeal Tremor ,Adductor laryngeal dystonia (ADLD) previously called spasmodic dysphonia Abductor laryngeal dystonia (ABLD) Vocal tremor Mixed laryngeal dystonia Singer's laryngeal dystonia (SLD) Adductor laryngeal spasms during inspiration (ARLD) , ,Laryngoscopy Images Stroboscopy Videos +Vocal Disorders Cohort ,Unilateral Vocal Fold Paralysis ,Laryngology & SLP diagnosis ,Vocal fold paresis Bilateral VF paralysis Immediately or less than 2 weeks post injection Immediately post-op thyroplasty (less than a month) ,Laryngoscopy Images Stroboscopy Videos CT scan Spirometry +Vocal Disorders Cohort ,Glottic insufficiency/presbyphonia ,"Patients with glottic gap on STROBOSCOPY due to vocal fold atrophy related to aging, rapid weight loss, severe illness, or other causes ",Patients with glottic gap 2nd to unilateral paresis or paralysis , +Respiratory Disorders Cohort ,"Airway Stenosis: Bilateral Vocal fold paralysis, Supraglottic stenosis, Glottic stenosis, Posterior glottic stenosis, subglottic stenosis, tracheal stenosis, multi-level upper airway stenosis ", ,Nasopharyngeal stenosis ,Spirometry and flow volume loops CT scan of neck/chest +Respiratory Disorders Cohort ,Chronic Cough ,"bothersome cough > 8 weeks, negative for exclusion criteria ","Cough less than 8 weeks, current smoking, lung/laryngeal cancer, COPD, asthma, GERD, bronchiectasis, TB infection, pneumonia, pulmonary granuloma, idiopathic pulmonary fibrosis, ACE inhibitor use, eosinophilic bronchitis, tracheomalacia, upper airway cough syndrome, laryngitis, chest Xray/CT indicative of airway foreign body ",Spirometry and flow volume loops +Neurological and Neurodegenerative Disorders ,Mild Cognitive Impairment (MCI) ,"clinical diagnosis of MCI/ cognitive decline/short term memory loss/cognitively impaired Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Whole Genome Sequencing +Neurological and Neurodegenerative Disorders ,Alzheimer's disease (AD) ,"clinical diagnosis of AD Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Serum Bloodmarker Ptau proteins Whole Genome Sequencing +Neurological and Neurodegenerative Disorders ,Other types of Dementia ,"clinical diagnosis of frontotemporal dementia/ Lewy body dementia/ vascular dementia/ mixed dementia/ alcohol induced dementia (to make a note in diagnosis form) Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Whole Genome Sequencing +Neurological and Neurodegenerative Disorders ,Amyotrophic Lateral Sclerosis (ALS) ,"clinical diagnosis of sporadic ALS/ Familial ALS/ Spinal or limb-onset ALS/ Bulbar-onset ALS Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Whole Genome Sequencing +Neurological and Neurodegenerative Disorders ,Parkinson's Disease (PD) ,clinical diagnosis of idiopathic PD/multiple system atrophy/progressive Supranuclear palsy/ Corticobasal degeneration/dementia with Lewy bodies/other or atypical parkinsonism Parkinson's patients enrolled in Deep Brain Stimulation studies (to make a note of this in diagnosis form) ,Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Whole Genome Sequencing +Mood and Psychiatric Disorders ,Alcohol or Substance Use Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Anxiety Disorder ,Existing clinical diagnosis of anxiety and/or currently experiencing an anxious episode. ,Not having a clinical diagnosis ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Attention-Deficit/Hyperactivity Disorder (ADHD) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Q-Mood-ADHD Adult questionnaire is part of part B mood cohort ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Autism Spectrum Disorder (ASD) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Bipolar Disorder ,Existing clinical diagnosis of bipolar I or II and/or currently experiencing a manic/depressive episode. ,Not having a clinical diagnosis ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Borderline Personality Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Depression or Major Depressive Disorder ,Existing clinical diagnosis of depression and/or currently experiencing a depressive episode. ,Not having a clinical diagnosis ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Eating Disorder (ED) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Insomnia/Sleep Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Obsessive-Compulsive Disorder (OCD) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Panic Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Post-Traumatic Stress Disorder (PTSD) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Q-Mood-PTSD Adult questionnaire is part of part B of mood cohort ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Schizophrenia ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Social Anxiety Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Q-Mood-GAD7 questionnaire is part of part B of mood cohort ,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders ,Other Psychiatric Disorder ,Not applicable ,Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history \ No newline at end of file diff --git a/src/tabs/tables/Validated_Questionnaires.csv b/src/tabs/tables/Validated_Questionnaires.csv new file mode 100644 index 0000000..afffc41 --- /dev/null +++ b/src/tabs/tables/Validated_Questionnaires.csv @@ -0,0 +1,13 @@ +Validated Questionnaire,Voice Disorders,Respiratory,Mood/Psychiatric,Neurological,Controls +Voice Handicap Index-10 (VHI-10),X,X,X,X,X +Patient Health Questionnaire (PHQ-9),X,X,X,X,X +General Anxiety Disorder (GAD-7),X,X,X,X,X +Positive and Negative Affect Schedule (PANAS),,,X,,X +Custom Affect scale,,,X,,X +Post-Traumatic Stress Disorder Test (PTSD) Adult,,,X,,X +Attention Deficit and Hyperactivity Disorder Questionnaire (ADHD-Adult),,,X,,X +The Diagnostic and Statistical Manual of Mental Disorders (DSM-5 Adult),,,X,,X +Dyspnea Index (DI),,X,,,X +Leicester Cough Questionnaire (LCQ),,X,,,X +Winograd Questionnaire,,,,X,X +Montreal Cognitive Assessment (MOCA)*,,,,X,X diff --git a/src/tabs/utils.py b/src/tabs/utils.py index ffde6aa..db53de0 100644 --- a/src/tabs/utils.py +++ b/src/tabs/utils.py @@ -1,4 +1,5 @@ import streamlit as st +import pandas as pd # All tab pages are defined below def coming_soon_message(tab_name): @@ -6,4 +7,51 @@ def coming_soon_message(tab_name): st.write(f"{tab_name} - Coming soon!") image_path = "images/Wave.png" - st.image(image_path, caption='', use_column_width=True) + st.image(image_path, caption='', use_container_width=True) + +def create_html_table(csv_file_path, caption=None): + # Read CSV file + df = pd.read_csv(csv_file_path, dtype=str) # Ensure all columns are read as strings + + # Replace NaN with an empty string; + df = df.fillna("") + + # Convert DataFrame to HTML table + html_table = df.to_html(index=False, classes='table table-striped') + + if caption: + html_table_with_caption = f""" + + + {html_table} +
+ {caption} +
+ """ + else: + html_table_with_caption = f""" + + {html_table} +
+ """ + + # Add CSS for table styling + st.markdown( + """ + + """, + unsafe_allow_html=True + ) + + # Display HTML table + st.markdown(html_table_with_caption, unsafe_allow_html=True) From 12f830c40b7d0f873943f1bfe0e8c3c326ba1756 Mon Sep 17 00:00:00 2001 From: Jeff Tang <47529643+jmtang2018@users.noreply.github.com> Date: Wed, 20 Nov 2024 10:27:16 -0500 Subject: [PATCH 07/18] minor --- src/tabs/ai_readiness.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tabs/ai_readiness.py b/src/tabs/ai_readiness.py index 3eb9c1d..5a32d1d 100644 --- a/src/tabs/ai_readiness.py +++ b/src/tabs/ai_readiness.py @@ -1,7 +1,6 @@ import streamlit as st # from tabs.utils import coming_soon_message from tabs.utils import create_html_table -from tabs.utils import create_html_table_span_col_row import pandas as pd import numpy as np From aab1f537f3e00f707f22e6c40f5e27c6e7e07fb6 Mon Sep 17 00:00:00 2001 From: Jeff Tang <47529643+jmtang2018@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:11:51 -0500 Subject: [PATCH 08/18] minor fixed --- src/tabs/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tabs/utils.py b/src/tabs/utils.py index db53de0..4a73ffd 100644 --- a/src/tabs/utils.py +++ b/src/tabs/utils.py @@ -19,7 +19,7 @@ def create_html_table(csv_file_path, caption=None): # Convert DataFrame to HTML table html_table = df.to_html(index=False, classes='table table-striped') - if caption: + if caption is not None: html_table_with_caption = f""" ', f'') + if caption is not None: html_table_with_caption = f"""
From 2b4aa81c6645b530950dc7e63343df0cc98d8918 Mon Sep 17 00:00:00 2001 From: Jeff Tang <47529643+jmtang2018@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:24:03 -0500 Subject: [PATCH 09/18] updated requirements.txt --- requirements.txt | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/requirements.txt b/requirements.txt index 0613417..3d7a989 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,42 +1,42 @@ altair==5.4.1 attrs==24.2.0 -blinker==1.8.2 +blinker==1.9.0 cachetools==5.5.0 certifi==2024.8.30 -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 click==8.1.7 gitdb==4.0.11 GitPython==3.1.43 idna==3.10 Jinja2==3.1.4 jsonschema==4.23.0 -jsonschema-specifications==2023.12.1 +jsonschema-specifications==2024.10.1 markdown-it-py==3.0.0 -MarkupSafe==2.1.5 +MarkupSafe==3.0.2 mdurl==0.1.2 -narwhals==1.8.1 -numpy==2.1.1 -packaging==24.1 -pandas==2.2.2 -pillow==10.4.0 +narwhals==1.14.1 +numpy==2.1.3 +packaging==24.2 +pandas==2.2.3 +pillow==11.0.0 plotly==5.24.1 -protobuf==5.28.2 -pyarrow==17.0.0 +protobuf==5.28.3 +pyarrow==18.0.0 pydeck==0.9.1 Pygments==2.18.0 python-dateutil==2.9.0.post0 pytz==2024.2 referencing==0.35.1 requests==2.32.3 -rich==13.8.1 -rpds-py==0.20.0 +rich==13.9.4 +rpds-py==0.21.0 six==1.16.0 smmap==5.0.1 -streamlit==1.38.0 -tenacity==8.5.0 +streamlit==1.40.1 +tenacity==9.0.0 toml==0.10.2 tornado==6.4.1 typing_extensions==4.12.2 -tzdata==2024.1 +tzdata==2024.2 urllib3==2.2.3 -watchdog==4.0.2 +watchdog==6.0.0 \ No newline at end of file From b0cc964947a40881f02b46b93b1644a8dd1259ec Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Wed, 20 Nov 2024 13:05:09 -0500 Subject: [PATCH 10/18] B2AI-544 --- src/tabs/ai_readiness.py | 949 +----------------- src/tabs/collection_methods.py | 51 +- src/tabs/overview.py | 2 +- ...se_cohort_inclusion_exclusion_criteria.csv | 31 - .../Acoustic_Tasks_Protocol.csv | 10 +- ...se_cohort_inclusion_exclusion_criteria.csv | 31 + .../Validated_Questionnaires.csv | 0 7 files changed, 87 insertions(+), 987 deletions(-) delete mode 100644 src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv rename {src/tabs/tables => tables}/Acoustic_Tasks_Protocol.csv (77%) create mode 100644 tables/Disease_cohort_inclusion_exclusion_criteria.csv rename {src/tabs/tables => tables}/Validated_Questionnaires.csv (100%) diff --git a/src/tabs/ai_readiness.py b/src/tabs/ai_readiness.py index 5a32d1d..9a4733e 100644 --- a/src/tabs/ai_readiness.py +++ b/src/tabs/ai_readiness.py @@ -1,5 +1,4 @@ import streamlit as st -# from tabs.utils import coming_soon_message from tabs.utils import create_html_table import pandas as pd @@ -16,7 +15,6 @@ def ai_readiness_page(tab_name): lt, cent, rt = st.columns([1,3,1], gap="small") with cent: st.image(image_path, use_container_width=True) - # Add Table st.markdown( @@ -35,7 +33,7 @@ def ai_readiness_page(tab_name): @@ -172,948 +170,3 @@ def ai_readiness_page(tab_name): """, unsafe_allow_html=True ) - - # st.markdown( - # """ - #
- Precision Public Health (Voice) - Current Rating + Table 4 - Precision Public Health (Voice) - Current Rating
Criterion
- # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - # - #
- #

 

- #
- #

 

- #
- #

 

- #
- #

 

- #
- #

Precision Public Health (Voice) - Current Rating

- #
- #

Criterion

- #
- #

Criterion met? (Y=1; N=0)

- #
- #

Total Score for Criterion (%)

- #
- #

FAIRness (0)

- #
- #

Findable - # (0.a)

- #
- #

1

- #
- #

100

- #
- #

Accessible - # (0.b)

- #
- #

1

- #
- #

Interoperable - # (0.c)

- #
- #

1

- #
- #

Reusable - # (0.d)

- #
- #

1

- #
- #

Provenance - # (1)

- #
- #

Transparent - # (1.a)

- #
- #

1

- #
- #

100

- #
- #

Traceable - # (1.b)

- #
- #

1

- #
- #

Interpretable - # (1.c)

- #
- #

1

- #
- #

Key actors identified - # (1.d)

- #
- #

1

- #
- #

Characterization - # (2)

- #
- #

Semantics - # (2.a)

- #
- #

1

- #
- #

80

- #
- #

Statistics - # (2.b)

- #
- #

1

- #
- #

Standards - # (2.c)

- #
- #

1

- #
- #

Potential - # Sources of Bias (2.d)

- #
- #

1

- #
- #

Data - # Quality (2.e)

- #
- #

0

- #
- #

Pre-model - # explainability (3)

- #
- #

Data - # documentation templates (3.a)

- #
- #

1

- #
- #

100

- #
- #

Fit for purpose - # (3.c)

- #
- #

1

- #
- #

Verifiable - # (3.d)

- #
- #

1

- #
- #

Ethics (4)

- #
- #

Ethically - # acquired (4.a)

- #
- #

1

- #
- #

100

- #
- #

Ethically - # managed (4.b)

- #
- #

1

- #
- #

Ethically - # disseminated (4.c)

- #
- #

1

- #
- #

Secure - # (4.d)

- #
- #

1

- #
- #

Sustainability - # (5)

- #
- #

Persistent - # (5.a)

- #
- #

1

- #
- #

50

- #
- #

Domain-appropriate - # (5.b)

- #
- #

0

- #
- #

Well-governed - # (5.c)

- #
- #

1

- #
- #

Associated - # (5.d)

- #
- #

0

- #
- #

Computability - # (6)

- #
- #

Standardized - # (6.a)

- #
- #

1

- #
- #

75

- #
- #

Computational - # Accessibility (6.b)

- #
- #

1

- #
- #

Portable - # (6.c)

- #
- #

1

- #
- #

Contextualized - # (6.d)

- #
- #

0

- #
- # """, - # unsafe_allow_html=True - # ) - # df = pd.DataFrame( - # np.random.randn(10, 5), columns=("col %d" % i for i in range(5)) - # ) - - # st.table(df) - - # MOVE TO "SECTION: Collection methods" - csv_file_path = "src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv" - caption = 'Table 1. Disease cohort inclusion/exclusion criteria and validation methods' - create_html_table(csv_file_path, caption) - - csv_file_path = "src/tabs/tables/Acoustic_Tasks_Protocol.csv" - caption = 'Table 2. Acoustic Tasks in Protocol' - create_html_table(csv_file_path, caption) - - csv_file_path = "src/tabs/tables/Validated_Questionnaires.csv" - caption = 'Table 3 Validated Questionnaires integrated into App' - create_html_table(csv_file_path, caption) - diff --git a/src/tabs/collection_methods.py b/src/tabs/collection_methods.py index 0e844c7..6d99b24 100644 --- a/src/tabs/collection_methods.py +++ b/src/tabs/collection_methods.py @@ -1,5 +1,52 @@ import streamlit as st -from tabs.utils import coming_soon_message +from tabs.utils import create_html_table def collection_methods_page(tab_name): - coming_soon_message(tab_name) \ No newline at end of file + + st.markdown( + + """ + Data is collected across five disease categories. Initial data release contains data collected from four of five categories (pediatric data to be incorporated in subsequent dataset releases. + + Participants are recruited across different academic institutions from “high volume expert clinics” based on diagnosis and inclusion/exclusion criteria outlined below **(Table 1)**. + + **High Volume Expert Clinics:** Outpatient clinics within hospital systems or academic institutions that have developed an expertise in a specific disease area and see more than 50 patients per month from the same disease category. Ex: Asthma/COPD pulmonary specialty clinic. + + Data is collected in the clinic with the assistance of a trained researched assistant. Future data collection will also occur remotely, however remote data collection did not occur with initial dataset being released. Voice samples are collected prospectively using a custom software application (Bridge2AI-Voice app) with the Bridge2AI-Voice protocols. + + **Clinical validation:** Clinical validation is performed by qualified physician or practitioner based on established gold standards for diagnosis **(Table 1)**. + + **Acoustic Tasks:** Voice, breathing, cough, and speech data are recorded with the app. A total of 22 acoustic Tasks are recorded through the app **(Table 2)**. + + **Demographic surveys and confounders:** Detailed demographic data and surveys about confounding factors such as smoking and drinking history is collected through the smartphone application. + + **Validated Questionnaires:** The Bridge2AI-Voice protocols contain validated tools and questionnaires for each disease category within the app for data collection **(Table 3)**. + + **Other Multimodal Data:** The rest of the multimodal data including imaging, genomic data (for the neuro cohort), laryngoscopy imaging and other EHR data is extracted from different sites independently and will be uploaded through the REDCAP database. Please note that no external data is released in this v1.0.0. + + Please see publication for protocol development description: + >Bensoussan, Yael, et al. "Developing Multi-Disorder Voice Protocols: A team science approach involving clinical expertise, bioethics, standards, and DEI." Proc. Interspeech 2024. 2024. [https://www.isca-archive.org/interspeech_2024/bensoussan24_interspeech.html](https://www.isca-archive.org/interspeech_2024/bensoussan24_interspeech.html). + + The supporting REDCap Data Dictionary, Metadata and Instrument PDF’s are available at [https://github.com/eipm/bridge2ai-redcap](https://github.com/eipm/bridge2ai-redcap) . + + When using the REDCap Data Dictionary and Metadata please cite: + + >Bensoussan, Y., Ghosh, S. S., Rameau, A., Boyer, M., Bahr, R., Watts, S., Rudzicz, F., Bolser, D., Lerner-Ellis, J., Awan, S., Powell, M. E., Belisle-Pipon, J.-C., Ravitsky, V., Johnson, A., Zisimopoulos, P., Tang, J., Sigaras, A., Elemento, O., Dorr, D., … Bridge2AI-Voice. (2024). eipm/bridge2ai-redcap. Zenodo. [https://zenodo.org/doi/10.5281/zenodo.12760724](https://zenodo.org/doi/10.5281/zenodo.12760724). + + + Protocols can be found in the Bridge2AI-Voice documentation for v1.0.0 of the dataset at [https://kind-lab.github.io/vbai-fhir/protocol.html](https://kind-lab.github.io/vbai-fhir/protocol.html). + + """ + ) + + csv_file_path = "tables/Disease_cohort_inclusion_exclusion_criteria.csv" + caption = 'Table 1 - Disease cohort inclusion/exclusion criteria and validation methods' + create_html_table(csv_file_path, caption) + + csv_file_path = "tables/Acoustic_Tasks_Protocol.csv" + caption = 'Table 2 - Acoustic Tasks in Protocol' + create_html_table(csv_file_path, caption) + + csv_file_path = "tables/Validated_Questionnaires.csv" + caption = 'Table 3 - Validated Questionnaires integrated into App' + create_html_table(csv_file_path, caption) diff --git a/src/tabs/overview.py b/src/tabs/overview.py index bda563f..d50deb8 100644 --- a/src/tabs/overview.py +++ b/src/tabs/overview.py @@ -21,7 +21,7 @@ def overview_page(tab_name): - Respiratory disorders - Pediatric Voice and Speech Disorders - Please Note: This V1.0 of the public data release does not contain pediatric data. It also does not contain an equal distribution of these categories of diseases. Further releases will contain additional data. + **Please Note:** This v1.0.0 of the public data release does not contain pediatric data. It also does not contain an equal distribution of these categories of diseases. Further releases will contain additional data. """ ) \ No newline at end of file diff --git a/src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv b/src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv deleted file mode 100644 index 1b4a86a..0000000 --- a/src/tabs/tables/Disease_cohort_inclusion_exclusion_criteria.csv +++ /dev/null @@ -1,31 +0,0 @@ -Disease Cohort ,Diagnosis ,Inclusion Criteria ,Exclusion Criteria ,Gold Standard Validation Methods -Vocal Disorders Cohort ,Laryngeal Cancer ,"Active laryngeal cancer T1-T4 Biopsy proven (if no biopsy at time of collection and suspicion is very high, provider will have to go back to confirm in the clinical validation section after the biopsy is obtained) ",Previously treated laryngeal cancer with no evidence of disease on scope ,Laryngoscopy Images Stroboscopy Videos -Vocal Disorders Cohort ,Laryngitis ,Acute laryngitis Chronic laryngitis Bacterial laryngitis Fungal laryngitis Autoimmune laryngitis *need to have evidence of information of the vocal cords on laryngoscopy as well as dysphonia ,Subjective laryngitis without evidence on scope ,Laryngoscopy Images Stroboscopy Videos -Vocal Disorders Cohort ,Pre-cancerous lesions ,Keratosis Leukoplakia (note if with or without dysplasia) ,Low grade - ,Laryngoscopy Images Stroboscopy Videos -Vocal Disorders Cohort ,"Benign Lesions of the vocal cord (nodule, polyp, cyst) ",Vocal fold nodules Vocal fold polyp Vocal fold cyst Reinke's Edema Vocal fold ulcers Recurrent respiratory Papilloma Fibrous mass Rheumatoid nodules Recurrent Laryngeal Papilloma (RLP) ,Patient has received surgery for any condition and does not have evidence of pathology when scoped Immediate post op prior less than 30 days from laryngeal surgery ,Laryngoscopy Images Stroboscopy Videos -Vocal Disorders Cohort ,Muscle Tension Dysphonia (MTD) ,Laryngology & SLP diagnosis , ,Laryngoscopy Images Stroboscopy Videos -Vocal Disorders Cohort ,Spasmodic Dysphonia/Laryngeal Tremor ,Adductor laryngeal dystonia (ADLD) previously called spasmodic dysphonia Abductor laryngeal dystonia (ABLD) Vocal tremor Mixed laryngeal dystonia Singer's laryngeal dystonia (SLD) Adductor laryngeal spasms during inspiration (ARLD) , ,Laryngoscopy Images Stroboscopy Videos -Vocal Disorders Cohort ,Unilateral Vocal Fold Paralysis ,Laryngology & SLP diagnosis ,Vocal fold paresis Bilateral VF paralysis Immediately or less than 2 weeks post injection Immediately post-op thyroplasty (less than a month) ,Laryngoscopy Images Stroboscopy Videos CT scan Spirometry -Vocal Disorders Cohort ,Glottic insufficiency/presbyphonia ,"Patients with glottic gap on STROBOSCOPY due to vocal fold atrophy related to aging, rapid weight loss, severe illness, or other causes ",Patients with glottic gap 2nd to unilateral paresis or paralysis , -Respiratory Disorders Cohort ,"Airway Stenosis: Bilateral Vocal fold paralysis, Supraglottic stenosis, Glottic stenosis, Posterior glottic stenosis, subglottic stenosis, tracheal stenosis, multi-level upper airway stenosis ", ,Nasopharyngeal stenosis ,Spirometry and flow volume loops CT scan of neck/chest -Respiratory Disorders Cohort ,Chronic Cough ,"bothersome cough > 8 weeks, negative for exclusion criteria ","Cough less than 8 weeks, current smoking, lung/laryngeal cancer, COPD, asthma, GERD, bronchiectasis, TB infection, pneumonia, pulmonary granuloma, idiopathic pulmonary fibrosis, ACE inhibitor use, eosinophilic bronchitis, tracheomalacia, upper airway cough syndrome, laryngitis, chest Xray/CT indicative of airway foreign body ",Spirometry and flow volume loops -Neurological and Neurodegenerative Disorders ,Mild Cognitive Impairment (MCI) ,"clinical diagnosis of MCI/ cognitive decline/short term memory loss/cognitively impaired Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Whole Genome Sequencing -Neurological and Neurodegenerative Disorders ,Alzheimer's disease (AD) ,"clinical diagnosis of AD Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Serum Bloodmarker Ptau proteins Whole Genome Sequencing -Neurological and Neurodegenerative Disorders ,Other types of Dementia ,"clinical diagnosis of frontotemporal dementia/ Lewy body dementia/ vascular dementia/ mixed dementia/ alcohol induced dementia (to make a note in diagnosis form) Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Whole Genome Sequencing -Neurological and Neurodegenerative Disorders ,Amyotrophic Lateral Sclerosis (ALS) ,"clinical diagnosis of sporadic ALS/ Familial ALS/ Spinal or limb-onset ALS/ Bulbar-onset ALS Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Whole Genome Sequencing -Neurological and Neurodegenerative Disorders ,Parkinson's Disease (PD) ,clinical diagnosis of idiopathic PD/multiple system atrophy/progressive Supranuclear palsy/ Corticobasal degeneration/dementia with Lewy bodies/other or atypical parkinsonism Parkinson's patients enrolled in Deep Brain Stimulation studies (to make a note of this in diagnosis form) ,Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied ,CT Brain MRI Brain Whole Genome Sequencing -Mood and Psychiatric Disorders ,Alcohol or Substance Use Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Anxiety Disorder ,Existing clinical diagnosis of anxiety and/or currently experiencing an anxious episode. ,Not having a clinical diagnosis ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Attention-Deficit/Hyperactivity Disorder (ADHD) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Q-Mood-ADHD Adult questionnaire is part of part B mood cohort ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Autism Spectrum Disorder (ASD) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Bipolar Disorder ,Existing clinical diagnosis of bipolar I or II and/or currently experiencing a manic/depressive episode. ,Not having a clinical diagnosis ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Borderline Personality Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Depression or Major Depressive Disorder ,Existing clinical diagnosis of depression and/or currently experiencing a depressive episode. ,Not having a clinical diagnosis ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Eating Disorder (ED) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Insomnia/Sleep Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Obsessive-Compulsive Disorder (OCD) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Panic Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Post-Traumatic Stress Disorder (PTSD) ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Q-Mood-PTSD Adult questionnaire is part of part B of mood cohort ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Schizophrenia ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Social Anxiety Disorder ,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Q-Mood-GAD7 questionnaire is part of part B of mood cohort ,Electronic health summary; clinical diagnosis from psychiatrist; medication history -Mood and Psychiatric Disorders ,Other Psychiatric Disorder ,Not applicable ,Not applicable ,Electronic health summary; clinical diagnosis from psychiatrist; medication history \ No newline at end of file diff --git a/src/tabs/tables/Acoustic_Tasks_Protocol.csv b/tables/Acoustic_Tasks_Protocol.csv similarity index 77% rename from src/tabs/tables/Acoustic_Tasks_Protocol.csv rename to tables/Acoustic_Tasks_Protocol.csv index 02c05e7..d1181a0 100644 --- a/src/tabs/tables/Acoustic_Tasks_Protocol.csv +++ b/tables/Acoustic_Tasks_Protocol.csv @@ -3,11 +3,11 @@ Non Voice/Non Speech,Respiration Part A,Breathing sounds,A Non Voice/Non Speech,Cough part A,Voluntary Cough,A Non Voice/Non Speech,Breath Sounds,Breathing sounds,Resp Non Voice/Non Speech,Voluntary Cough,Voluntary Cough,Resp -Voice / Non Speech,Prolonged Vowel,vowel /e/,A -Voice / Non Speech,Maximum Phonation Time,vowel /e/,A -Voice / Non Speech,Glides,Lowest to Highest /e/,A -Voice / Non Speech,Loudness,/Hey/,A -Voice / Non Speech,Diadochokinesis,/pa/ta/ka/ /buttercup/,A +Voice/Non Speech,Prolonged Vowel,vowel /e/,A +Voice/Non Speech,Maximum Phonation Time,vowel /e/,A +Voice/Non Speech,Glides,Lowest to Highest /e/,A +Voice/Non Speech,Loudness,/Hey/,A +Voice/Non Speech,Diadochokinesis,/pa/ta/ka/ /buttercup/,A Speech,Rainbow Passage,validated passage,A Speech,Caterpillar Passage,validated passage,Voice Speech,Cape-V Sentences,validated sentences,Voice diff --git a/tables/Disease_cohort_inclusion_exclusion_criteria.csv b/tables/Disease_cohort_inclusion_exclusion_criteria.csv new file mode 100644 index 0000000..3f88bdf --- /dev/null +++ b/tables/Disease_cohort_inclusion_exclusion_criteria.csv @@ -0,0 +1,31 @@ +Disease Cohort,Diagnosis,Inclusion Criteria,Exclusion Criteria,Gold Standard Validation Methods +Voice Disorders Cohort,Laryngeal Cancer,"Active laryngeal cancer T1-T4 Biopsy proven (if no biopsy at time of collection and suspicion is very high, provider will have to go back to confirm in the clinical validation section after the biopsy is obtained) ",Previously treated laryngeal cancer with no evidence of disease on scope,Laryngoscopy Images Stroboscopy Videos +Voice Disorders Cohort,Laryngitis,Acute laryngitis Chronic laryngitis Bacterial laryngitis Fungal laryngitis Autoimmune laryngitis *need to have evidence of information of the vocal cords on laryngoscopy as well as dysphonia,Subjective laryngitis without evidence on scope,Laryngoscopy Images Stroboscopy Videos +Voice Disorders Cohort,Pre-cancerous lesions,Keratosis Leukoplakia (note if with or without dysplasia),Low grade -,Laryngoscopy Images Stroboscopy Videos +Voice Disorders Cohort,"Benign Lesions of the vocal cord (nodule, polyp, cyst) ",Vocal fold nodules Vocal fold polyp Vocal fold cyst Reinke's Edema Vocal fold ulcers Recurrent respiratory Papilloma Fibrous mass Rheumatoid nodules Recurrent Laryngeal Papilloma (RLP),Patient has received surgery for any condition and does not have evidence of pathology when scoped Immediate post op prior less than 30 days from laryngeal surgery,Laryngoscopy Images Stroboscopy Videos +Voice Disorders Cohort,Muscle Tension Dysphonia (MTD),Laryngology & SLP diagnosis,,Laryngoscopy Images Stroboscopy Videos +Voice Disorders Cohort,Spasmodic Dysphonia/Laryngeal Tremor,Adductor laryngeal dystonia (ADLD) previously called spasmodic dysphonia Abductor laryngeal dystonia (ABLD) Vocal tremor Mixed laryngeal dystonia Singer's laryngeal dystonia (SLD) Adductor laryngeal spasms during inspiration (ARLD),,Laryngoscopy Images Stroboscopy Videos +Voice Disorders Cohort,Unilateral Vocal Fold Paralysis,Laryngology & SLP diagnosis,Vocal fold paresis Bilateral VF paralysis Immediately or less than 2 weeks post injection Immediately post-op thyroplasty (less than a month),Laryngoscopy Images Stroboscopy Videos CT scan Spirometry +Voice Disorders Cohort,Glottic insufficiency/presbyphonia,"Patients with glottic gap on STROBOSCOPY due to vocal fold atrophy related to aging, rapid weight loss, severe illness, or other causes ",Patients with glottic gap 2nd to unilateral paresis or paralysis, +Respiratory Disorders Cohort,"Airway Stenosis: Bilateral Vocal fold paralysis, Supraglottic stenosis, Glottic stenosis, Posterior glottic stenosis, subglottic stenosis, tracheal stenosis, multi-level upper airway stenosis ",,Nasopharyngeal stenosis,Spirometry and flow volume loops CT scan of neck/chest +Respiratory Disorders Cohort,Chronic Cough,"bothersome cough > 8 weeks, negative for exclusion criteria ","Cough less than 8 weeks, current smoking, lung/laryngeal cancer, COPD, asthma, GERD, bronchiectasis, TB infection, pneumonia, pulmonary granuloma, idiopathic pulmonary fibrosis, ACE inhibitor use, eosinophilic bronchitis, tracheomalacia, upper airway cough syndrome, laryngitis, chest Xray/CT indicative of airway foreign body ",Spirometry and flow volume loops +Neurological and Neurodegenerative Disorders,Mild Cognitive Impairment (MCI),"clinical diagnosis of MCI/ cognitive decline/short term memory loss/cognitively impaired Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied,CT Brain MRI Brain Whole Genome Sequencing +Neurological and Neurodegenerative Disorders,Alzheimer's disease (AD),"clinical diagnosis of AD Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied,CT Brain MRI Brain Serum Bloodmarker Ptau proteins Whole Genome Sequencing +Neurological and Neurodegenerative Disorders,Other types of Dementia,"clinical diagnosis of frontotemporal dementia/ Lewy body dementia/ vascular dementia/ mixed dementia/ alcohol induced dementia (to make a note in diagnosis form) Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied,CT Brain MRI Brain Whole Genome Sequencing +Neurological and Neurodegenerative Disorders,Amyotrophic Lateral Sclerosis (ALS),"clinical diagnosis of sporadic ALS/ Familial ALS/ Spinal or limb-onset ALS/ Bulbar-onset ALS Being over the age of 44 and under 85 Able to read, speak the English language ",Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied,CT Brain MRI Brain Whole Genome Sequencing +Neurological and Neurodegenerative Disorders,Parkinson's Disease (PD),clinical diagnosis of idiopathic PD/multiple system atrophy/progressive Supranuclear palsy/ Corticobasal degeneration/dementia with Lewy bodies/other or atypical parkinsonism Parkinson's patients enrolled in Deep Brain Stimulation studies (to make a note of this in diagnosis form),Not having a clinical diagnosis Being less than the age of 44 and above 85 Unable to speak and read the English language Having had a surgical intervention significantly altering the symptoms of the disease studied,CT Brain MRI Brain Whole Genome Sequencing +Mood and Psychiatric Disorders,Alcohol or Substance Use Disorder,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Anxiety Disorder,Existing clinical diagnosis of anxiety and/or currently experiencing an anxious episode.,Not having a clinical diagnosis,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Attention-Deficit/Hyperactivity Disorder (ADHD),"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Q-Mood-ADHD Adult questionnaire is part of part B mood cohort,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Autism Spectrum Disorder (ASD),"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Bipolar Disorder,Existing clinical diagnosis of bipolar I or II and/or currently experiencing a manic/depressive episode.,Not having a clinical diagnosis,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Borderline Personality Disorder,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Depression or Major Depressive Disorder,Existing clinical diagnosis of depression and/or currently experiencing a depressive episode.,Not having a clinical diagnosis,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Eating Disorder (ED),"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Insomnia/Sleep Disorder,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Obsessive-Compulsive Disorder (OCD),"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Panic Disorder,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Post-Traumatic Stress Disorder (PTSD),"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Q-Mood-PTSD Adult questionnaire is part of part B of mood cohort,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Schizophrenia,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Not applicable,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Social Anxiety Disorder,"Co-morbid with depression, bipolar disorder and anxiety disorder. ",Q-Mood-GAD7 questionnaire is part of part B of mood cohort,Electronic health summary; clinical diagnosis from psychiatrist; medication history +Mood and Psychiatric Disorders,Other Psychiatric Disorder,Not applicable,Not applicable,Electronic health summary; clinical diagnosis from psychiatrist; medication history \ No newline at end of file diff --git a/src/tabs/tables/Validated_Questionnaires.csv b/tables/Validated_Questionnaires.csv similarity index 100% rename from src/tabs/tables/Validated_Questionnaires.csv rename to tables/Validated_Questionnaires.csv From d378810d6d01ccd101aa508187393a3ff60f4ee8 Mon Sep 17 00:00:00 2001 From: Jeff Tang <47529643+jmtang2018@users.noreply.github.com> Date: Wed, 20 Nov 2024 14:24:17 -0500 Subject: [PATCH 11/18] set cell value to center --- src/tabs/collection_methods.py | 2 +- src/tabs/utils.py | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/tabs/collection_methods.py b/src/tabs/collection_methods.py index 6d99b24..c806377 100644 --- a/src/tabs/collection_methods.py +++ b/src/tabs/collection_methods.py @@ -49,4 +49,4 @@ def collection_methods_page(tab_name): csv_file_path = "tables/Validated_Questionnaires.csv" caption = 'Table 3 - Validated Questionnaires integrated into App' - create_html_table(csv_file_path, caption) + create_html_table(csv_file_path, caption, ['X']) diff --git a/src/tabs/utils.py b/src/tabs/utils.py index 4a73ffd..da3ea6e 100644 --- a/src/tabs/utils.py +++ b/src/tabs/utils.py @@ -9,7 +9,7 @@ def coming_soon_message(tab_name): image_path = "images/Wave.png" st.image(image_path, caption='', use_container_width=True) -def create_html_table(csv_file_path, caption=None): +def create_html_table(csv_file_path, caption=None, cell_values=[]): # Read CSV file df = pd.read_csv(csv_file_path, dtype=str) # Ensure all columns are read as strings @@ -18,7 +18,10 @@ def create_html_table(csv_file_path, caption=None): # Convert DataFrame to HTML table html_table = df.to_html(index=False, classes='table table-striped') - + if cell_values and len(cell_values) > 0: + for cell_value in cell_values: + html_table = html_table.replace(f'
{cell_value}{cell_value}
@@ -48,6 +51,9 @@ def create_html_table(csv_file_path, caption=None): padding: 4px !important; text-align: left; } + .table .center-align { + text-align: center; /* Center alignment for specific columns */ + } """, unsafe_allow_html=True From 8aed5f5ae8d0b32858cda895fc4683e6debdce33 Mon Sep 17 00:00:00 2001 From: Jeff Tang <47529643+jmtang2018@users.noreply.github.com> Date: Wed, 20 Nov 2024 15:32:58 -0500 Subject: [PATCH 12/18] center cells for table4 --- src/tabs/ai_readiness.py | 74 +++++++++++++++++++++------------------- 1 file changed, 39 insertions(+), 35 deletions(-) diff --git a/src/tabs/ai_readiness.py b/src/tabs/ai_readiness.py index 9a4733e..ed55d53 100644 --- a/src/tabs/ai_readiness.py +++ b/src/tabs/ai_readiness.py @@ -29,6 +29,10 @@ def ai_readiness_page(tab_name): padding: 4px; text-align: left; } + + table .center-align { + text-align: center; + }
@@ -43,128 +47,128 @@ def ai_readiness_page(tab_name): - - + + - + - + - + - - + + - + - + - + - - + + - + - + - + - + - - + + - + - + - - + + - + - + - + - - + + - + - + - + - - + + - + - + - +
FAIRness (0) Findable (0.a)11001100
Accessible (0.b)11
Interoperable (0.c)11
Reusable (0.d)11
Provenance (1) Transparent (1.a)11001100
Traceable (1.b)11
Interpretable (1.c)11
Key actors identified (1.d)11
Characterization (2) Semantics (2.a)180180
Statistics (2.b)11
Standards (2.c)11
Potential Sources of Bias (2.d)11
Data Quality (2.e)00
Pre-model explainability (3) Data documentation templates (3.a)11001100
Fit for purpose (3.c)11
Verifiable (3.d)11
Ethics (4) Ethically acquired (4.a)11001100
Ethically managed (4.b)11
Ethically disseminated (4.c)11
Secure (4.d)11
Sustainability (5) Persistent (5.a)150150
Domain-appropriate (5.b)00
Well-governed (5.c)11
Associated (5.d)00
Computability (6) Standardized (6.a)175175
Computational Accessibility (6.b)11
Portable (6.c)11
Contextualized (6.d)00
""", From 6d374aa939927d2159abf4aa93099fa158537197 Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Wed, 20 Nov 2024 15:42:54 -0500 Subject: [PATCH 13/18] B2AI-544 --- src/bids-like_structure_preview.html | 362 -------------------------- src/dashboard.py | 5 - src/tabs/data_pre_processing.py | 89 ++++++- src/tabs/dataset_structure_preview.py | 20 -- 4 files changed, 87 insertions(+), 389 deletions(-) delete mode 100644 src/bids-like_structure_preview.html delete mode 100644 src/tabs/dataset_structure_preview.py diff --git a/src/bids-like_structure_preview.html b/src/bids-like_structure_preview.html deleted file mode 100644 index eaada2b..0000000 --- a/src/bids-like_structure_preview.html +++ /dev/null @@ -1,362 +0,0 @@ - - - - - - Bridge2AI Dataset Structure Preview - - - - - -
-
    -
    - - -
    -
    - - - - diff --git a/src/dashboard.py b/src/dashboard.py index fd10dce..696d338 100644 --- a/src/dashboard.py +++ b/src/dashboard.py @@ -12,8 +12,6 @@ from tabs.data_pre_processing import data_pre_processing_page from tabs.ai_readiness import ai_readiness_page -from tabs.dataset_structure_preview import dataset_structure_preview_page - def config_page(version): st.set_page_config( page_title="Bridge2AI Voice Dashboard", @@ -58,8 +56,6 @@ def main(): # data_pre_processing_page() is defined in tabs/data_pre_processing.py # ai_readiness_page() is defined in tabs/ai_readiness.py - # dataset_structure_preview_page() is defined in tabs/dataset_structure_preview.py - tab_functions = { "Overview": overview_page, "Collection Methods": collection_methods_page, @@ -69,7 +65,6 @@ def main(): "Healthsheet": healthsheet_page, "Data Pre-Processing": data_pre_processing_page, "AI-Readiness": ai_readiness_page, - "Dataset Structure Preview": dataset_structure_preview_page } # Set page configuration diff --git a/src/tabs/data_pre_processing.py b/src/tabs/data_pre_processing.py index 14d17fa..ac89c25 100644 --- a/src/tabs/data_pre_processing.py +++ b/src/tabs/data_pre_processing.py @@ -1,5 +1,90 @@ import streamlit as st -from tabs.utils import coming_soon_message def data_pre_processing_page(tab_name): - coming_soon_message(tab_name) \ No newline at end of file + st.markdown( + """ + The raw audio files and the questionnaire data exported from REDCap were converted to a BIDS-like structure as shown in the figure below. This dataset organization is based on Brain Imaging Data Structure v1.9.0. All questionnaires are represented with metadata available through FHIR (GitHub: [https://kind-lab.github.io/vbai-fhir/protocol.html](https://kind-lab.github.io/vbai-fhir/protocol.html) ) and ReproSchema ([https://github.com/sensein/b2ai-redcap2rs](https://github.com/sensein/b2ai-redcap2rs)). + + ``` + b2aiprep/src/b2aiprep/prepare/resources/b2ai-data-bids-like-template + ├── .pdf + ├── CHANGES.md + ├── README.md + ├── dataset_description.json + ├── participants.json + ├── participants.tsv + ├── phenotype + │   ├── .json + │   └── .tsv + └── sub- + ├── ses- + │   ├── beh + │   │   ├── sub-_ses-_task-_run-_metadata.json + │   │   └── sub-_ses-_task-_run-_response.json + │   └── voice + │   ├── sub-_ses-_task-_run-_audio.wav + │   ├── sub-_ses-_task-_run-_features.pt + │   ├── sub-_ses-_task-_run-_metadata.json + │   └── sub-_ses-_task-_run-_transcript.txt + ├── ses- + │   ├── beh + │   │   ├── sub-_ses-_task-_run-_metadata.json + │   │   └── sub-_ses-_task-_run-_response.json + │   └── voice + │   ├── sub-_ses-_task-_run-_audio.wav + │   ├── sub-_ses-_task-_run-_features.pt + │   ├── sub-_ses-_task-_run-_metadata.json + │   └── sub-_ses-_task-_run-_transcript.txt + └── sessions.tsv + ``` + + The dataset is then processed to extract features from each waveform. These include: + - OpenSmile eGeMaps features per audio file + - Parselmouth/Praat speech features for any speech tasks + - Speech intelligibility metrics for speech tasks + Time varying features + - Torchaudio-based pitch contour, spectrograms, mel spectrogram, and MFCCs + + **Speech tasks** + - Animal fluency + - Cape V sentences + - Caterpillar Passage + - Cinderella Story + - Diadochokinesis + - Free Speech + - Picture description + - Productive Vocabulary + - Prolonged vowel + - Rainbow Passage + - Random Item Generation + - Story recall + - Word-color Stroop + + **AI-Ready derived datasets** + The questionnaire features are combined into a single table. This can be used for cohort selection. + + The waveform features are stored using two formats: + 1. A fixed feature format that includes static features extracted from the entire waveform + 2. A temporal format that varies for each audio file depending on the length of recording. + + **Methods of De-identification for v1.0.0** + All direct identifiers were removed, as these would reveal the identity of the research participant. These include name, civic address, and social security numbers. Indirect identifiers were removed where these created a significant risk of causing participant re-identification, for example through their combination with other public data available on social media, in government registries, or elsewhere. These include select geographic or demographic identifiers, as well as some information about household composition or cultural identity. Non-identifying elements of data that revealed highly sensitive information, such as information about household income, mental health status, traumatic life experiences, and the like were also removed. All raw voice data was removed, as this data has the potential to cause to individual re-identification or to be used for illicit or unauthorized purposes. + + All sensitive fields are removed from the dataset at this stage. These correspond to data elements encoded as sensitive (Column name: Identifier?) available at: [https://github.com/eipm/bridge2ai-redcap/blob/main/data/bridge2ai_voice_project_data_dictionary.csv](https://github.com/eipm/bridge2ai-redcap/blob/main/data/bridge2ai_voice_project_data_dictionary.csv). + + In addition, all free text responses are evaluated for PII and removed when not appropriate. + + **Audit protocol** + - Generate missingness tables + - Check distributions and outliers + - For categorical responses, check against schema + - For waveforms: + - Check amount of silence + - Duration + - For speech, check produced speech relative to intended passage + + All processing is done using these toolkits: + - B2AIprep (organizing and preprocessing the dataset): [https://github.com/sensein/b2aiprep](https://github.com/sensein/b2aiprep) + - SenseLab (processing audio files for research tasks): [https://github.com/sensein/senselab](https://github.com/sensein/senselab) + """ + ) \ No newline at end of file diff --git a/src/tabs/dataset_structure_preview.py b/src/tabs/dataset_structure_preview.py deleted file mode 100644 index 7b68a9b..0000000 --- a/src/tabs/dataset_structure_preview.py +++ /dev/null @@ -1,20 +0,0 @@ -import streamlit as st -import os -import streamlit.components.v1 as components - -def dataset_structure_preview_page(tab_name): - st.title(f"{tab_name}") - - # Define the path to the HTML file - html_file_path = os.path.join(os.path.dirname(__file__), '../bids-like_structure_preview.html') - - # Check if the HTML file exists - if os.path.exists(html_file_path): - # Read the HTML file content - with open(html_file_path, 'r', encoding='utf-8') as file: - b2aipreview = file.read() - - # Display the HTML content in a scrollable iframe - components.html(b2aipreview, height=600, scrolling=True) - else: - st.error("Failed to load dataset structure preview. The HTML file was not found.") From 09dd502325c572d59b75c50cb26366ea84d3c2f4 Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Wed, 20 Nov 2024 17:58:58 -0500 Subject: [PATCH 14/18] B2AI-542 --- src/tabs/healthsheet.py | 331 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 329 insertions(+), 2 deletions(-) diff --git a/src/tabs/healthsheet.py b/src/tabs/healthsheet.py index 04850e8..cd5935c 100644 --- a/src/tabs/healthsheet.py +++ b/src/tabs/healthsheet.py @@ -1,6 +1,333 @@ import streamlit as st -from tabs.utils import coming_soon_message # Define the content of the Health Sheet page def healthsheet_page(tab_name): - coming_soon_message(tab_name) \ No newline at end of file + + st.subheader("**General Information**") + + st.markdown(''' + **Provide a 2-sentence summary of this dataset.** + + The Bridge2AI Voice dataset aims to enable the development, benchmarking, or validation of clinically applicable machine-learning models for diagnosing a wide range of health conditions using voice data, including vocal pathologies, neurological, psychiatric, respiratory, and pediatric voice disorders. This dataset contains voice recordings and key metadata and is structured to be Findable, Accessible, Interoperable, and Reusable (FAIR). + ''' + ) + + with st.expander("**Has the dataset been audited before? If yes, by whom and what are the results?**", expanded=False): + st.write('''The dataset has been audited internally for missingness and consistency by the data release team. A missingness table is included with the dataset. Certain aspects of the data (e.g., transcription) were generated using off the shelf models that have not been audited for correctness.''') + + st.subheader("**Dataset Versioning**") + + with st.expander("**Does the dataset get released as static versions or is it dynamically updated?**", expanded=False): + st.write('''Static''') + + with st.expander("**Does the current version/subversion of the dataset come with predefined task(s), labels, and recommended data splits (e.g., for training, development/validation, testing)? If yes, please provide a high-level description of the introduced tasks, data splits, and labeling, and explain the rationale behind them. Please provide the related links and references. If not, is there any resource (website, portal, etc.) to keep track of all defined tasks and/or associated label definitions? (please note that more detailed questions w.r.t labeling is provided in further sections)**", expanded=False): + st.write('''Yes, the current version of the dataset comes with predefined tasks and labeling. The tasks are primarily designed for training machine-learning models for disease detection and classification using voice data. Labels include diagnostic categories such as vocal pathologies, neurological disorders, psychiatric conditions, and respiratory disorders. However, there are no predefined recommended data splits for training, validation, or testing. Researchers are encouraged to create their own data splits based on their specific requirements. More details regarding task definitions and labeling can be found in the dataset.''') + + st.subheader("**Motivation**") + + with st.expander("**For what purpose was the dataset created? Was there a specific task in mind? Was there a specific gap that needed to be filled? Please provide a description.**", expanded=False): + st.write('''The Bridge2AI Voice dataset was created to address a gap in the availability of large-scale, diverse, and well-documented voice data for use in clinical machine-learning applications. Previous studies on machine learning-based voice diagnosis produced promising results, but their sample sizes were too small, or they lacked the key metadata needed for training robust, clinically useful models. The dataset aims to bridge this gap by providing an ethically sourced, large, and diverse dataset to develop, benchmark, or validate clinically applicable AI/ML models. The goal is to facilitate the use of voice as a non-invasive, cost-effective biomarker for the screening, diagnosis, and monitoring of a wide range of health conditions.''') + + with st.expander("**What are the applications that the dataset is meant to address? (e.g., administrative applications, software applications, research)**", expanded=False): + st.write('''The Bridge2AI Voice dataset is primarily intended for research applications, specifically in the development of AI and machine-learning models for healthcare. It aims to support clinical research in disease screening, diagnosis, and monitoring through voice biomarkers. The dataset can be used for AI model pretraining, finetuning, benchmarking, or validation.''') + + with st.expander("**Are there any types of usage or applications that are discouraged from using this dataset? If so, why?**", expanded=False): + st.write('''Yes, there are restrictions on the use of this dataset, as detailed in the Registered Data Access Agreement. These restrictions reflect the B2AI-Voice Consortium’s commitment to advancing ethical and trustworthy research practices that respect and protect the rights and interests of research participants. Accordingly, the dataset is intended solely for commercial and non-commercial research purposes by Authorized Researchers. Specifically, the dataset is not to be used a) to attempt to re-identify research participants, nor any actions that could reasonably lead to re-identification; and b) for any purpose that could foreseeably cause harm or stigmatization to research participants, their families, communities, or specific populations. Lastly, intellectual property protections, database rights, or related rights may not be used in a manner that restricts or limits access to any part of the dataset or to any conclusions derived from it. This restriction ensures that future use of the dataset remains unrestricted, in alignment with the Open Science principles upheld by the B2AI-Voice Consortium. Specifically, the dataset should not be used for non-research applications, such as hiring decisions, insurance premium adjustments, or any form of surveillance that could lead to discrimination or harm. These limitations are intended to prevent unethical or biased outcomes that could negatively impact individuals based on their health conditions or voice characteristics.''') + + with st.expander("**Who created this dataset (e.g., which team, research group), and on behalf of which entity (e.g., company, institution, organization)?**", expanded=False): + st.write('''Voice as a Biomarker of Health is being co-led by Dr Yaël Bensoussan, MD, MSc from USF Health Morsani College of Medicine and Olivier Elemento, PhD from Weill Cornell Medicine, who are co-principal investigators for the project, which is funded by the NIH Common Fund within the Bridge2AI Program. The project also includes lead investigators from 10 other universities in North America; Alexandros Sigaras, MSc and Anaïs Rameau, MD, MPhil (Weill Cornell Medicine), Maria Powell, CCC-SLP, PhD (Vanderbilt University Medical Center), Ruth Bahr, CCC-SLP, PhD (USF Health Morsani College of Medicine), Jennifer Sui, MD (Hospital for Sick Children), Philip Payne, PhD (Washington University in St. Louis), David Dorr, MD (Oregon Health & Science University), Jean-Christophe Bélisle-Pipon, PhD (Simon Fraser University), Vardit Ravitsky , PhD (The Hastings Center), Satrajit Ghosh, PhD (Massachusetts Institute of Technology), Frank Rudzizc, PhD (University of Toronto), Jordan Lerner-Ellis, PhD (Sinai Health) and Don Bolser, PhD (University of Florida).There are over 50 other investigators, clinicians, scholars and trainees who have contributed to the development of this dataset. Please see full list of collaborators here: [The Bridge2AI-Voice Consortium (2024)](https://b2ai-voice.org/wp-content/uploads/2024/11/FOR-WEBSITE-Year-2-Bridge2AI-Voice-Consortium-Authors.docx)''') + + with st.expander("**Who funded the creation of the dataset? If there is an associated grant, please provide the name of the grantor and the grant name and number. If the funding institution differs from the research organization creating and managing the dataset, please state how.**", expanded=False): + st.write('''The NIH Common Fund + [3TF- OT2ActfOD032720Projectf01S1](https://reporter.nih.gov/search/ES3d7yibyESXrX-rp6g1Ng/project-details/10858564)''') + + with st.expander("**What is the distribution of backgrounds and experience/expertise of the dataset curators/generators?**", expanded=False): + st.write('''The curators and generators of the Bridge2AI Voice dataset come from a diverse range of backgrounds and areas of expertise, reflecting the interdisciplinary nature of the project. The team includes: + 1. Clinicians and Healthcare Professionals: Practicing doctors and healthcare workers involved in the direct collection of clinical data and providing practical insights into the medical relevance of the dataset. + 2. Biomedical Researchers: Experts in clinical medicine, neurology, and psychiatry, contributing deep knowledge of the medical conditions being studied. + 3. Machine Learning and AI Specialists: Researchers and engineers with expertise in machine learning, artificial intelligence, and data science, focusing on developing models and algorithms for analyzing voice data. + 4. Data Scientists and Statisticians: Professionals skilled in data curation, preprocessing, and statistical analysis, ensuring the dataset is robust and suitable for machine learning applications. + 5. Social Scientists and Ethicists: Experts in ethics, sociology, and human subjects research, ensuring the dataset is ethically sourced and meets standards for privacy and consent. + 6. Engineers and Technologists: Individuals with experience in software development, systems engineering, and data infrastructure, contributing to the technical aspects of data collection, storage, and dissemination. + ''') + + st.subheader("**Data Composition**") + + with st.expander("**What do the instances that comprise the dataset represent (e.g., documents, images, people, countries)? Are there multiple types of instances? Please provide a description.**", expanded=False): + st.write('''Each instance represents a person.''') + + with st.expander("**How many instances are there in total (of each type, if appropriate) (breakdown based on schema, provide data stats)?**", expanded=False): + st.write('''There are currently around 307 instances.''') + + with st.expander("**How many patients/subjects does this dataset represent? Answer this for both the preliminary dataset and the current version of the dataset.**", expanded=False): + st.write('''307''') + + with st.expander("**Does the dataset contain all possible instances, or is it a sample (not necessarily random) of instances from a larger set? If the dataset is a sample, then what is the larger set? Is the sample representative of the larger set (e.g., geographic coverage)? If so, please describe how this representativeness was validated/verified. If it is not representative of the larger set, please describe why not (e.g., to cover a more diverse range of instances, because instances were withheld or unavailable). Answer this question for the preliminary version and the current version of the dataset in question.**", expanded=False): + st.write('''It is a sample of larger ongoing collection. The data is not representative because it was collected at a limited number of geographic locations. We hope to make it more representative by shifting to remote collection and designing our recruiting approach in a way that controls for more variables.''') + + with st.expander("**What data modality does each patient data consist of? If the data is hierarchical, provide the modality details for all levels (e.g., text, image, physiological signal). Break down all levels and specify the modalities and devices.**", expanded=False): + st.write('''Audio recordings, questionnaire responses.''') + + with st.expander("**What data does each instance consist of? “Raw” data (e.g., unprocessed text or images) or features? In either case, please provide a description.**", expanded=False): + st.write('''Raw audio and questionnaire response data, as well as extracted audio features.''') + + with st.expander("**Is any information missing from individual instances? If so, please provide a description, explaining why this information is missing (e.g., because it was unavailable).**", expanded=False): + st.write('''Yes, some questions are optional. There may be data collection irregularities that caused some information to be missing from individual instances. Each individual answered a common set of questions and then responded to a primary diagnostic category relevant additional questions.''') + + with st.expander("**Are relationships between individual instances made explicit? (e.g., They are all part of the same clinical trial, or a patient has multiple hospital visits, and each visit is one instance)? If so, please describe how these relationships are made explicit.**", expanded=False): + st.write('''No, they are unrelated.''') + + with st.expander("**Are there any errors, sources of noise, or redundancies in the dataset? If so, please provide a description. (e.g., losing data due to battery failure, or in survey data subjects skip the question, radiological sources of noise).**", expanded=False): + st.write('''Yes, different sites have different collection configurations. The collection protocol changed over the course of the study.''') + + with st.expander("**Are there any errors, sources of noise, or redundancies in the dataset? If so, please provide a description. (e.g., losing data due to battery failure, or in survey data subjects skip the question, radiological sources of noise).**", expanded=False): + st.write('''Yes, different sites have different collection configurations. The collection protocol changed over the course of the study.''') + + with st.expander("**Is the dataset self-contained, or does it link to or otherwise rely on external resources (e.g., websites, other datasets)? If it links to or relies on external resources:**", expanded=False): + st.write(''' + **a. Are there guarantees that they will exist, and remain constant, over time?** + + NA + + **b. Are there official archival versions of the complete dataset (i.e., including the external resources as they existed at the time the dataset was created)?** + + NA + + **c. Are there any restrictions (e.g., licenses, fees) associated with any of the external resources that might apply to a future user? Please provide descriptions of all external resources and any restrictions associated with them, as well as links or other access points, as appropriate.** + + It is self-contained. + ''') + + with st.expander("**Does the dataset contain data that might be considered confidential (e.g., data that is protected by legal privilege or by doctor-patient confidentiality, data that includes the content of individuals' non-public communications that is confidential)? If so, please provide a description.**", expanded=False): + st.write('''No''') + + with st.expander("**Does the dataset contain data that, if viewed directly, might be offensive, insulting, threatening, or might otherwise pose any safety risk (such as psychological safety and anxiety)? If so, please describe why.**", expanded=False): + st.write('''This dataset includes the transcription of free speech tasks. While the inclusion of information of that type is unlikely, it cannot be completely avoided, as research participants are responsible for their choice of language.''') + + with st.expander("**If the dataset has been de-identified, were any measures taken to avoid the re-identification of individuals? Examples of such measures: removing patients with rare pathologies or shifting time stamps.**", expanded=False): + st.write('''This dataset has been deidentified through removal of all audio data and certain sensitive fields identified by a team of ethicists.''') + + with st.expander("**Does the dataset contain data that might be considered sensitive in any way (e.g., data that reveals racial or ethnic origins, sexual orientations, religious beliefs, political opinions or union memberships, or locations; financial or health data; biometric or genetic data; forms of government identification, such as social security numbers; criminal history)? If so, please provide a description.**", expanded=False): + st.write(''' + Yes: + + **racial or ethnic origins**: The dataset includes race information. + + **sexual orientations**: The dataset includes sexual orientation information. + + **financial or health data**: The dataset includes socioeconomic and health information. + ''') + + st.subheader("**Devices and Contextual Attributes in Data Collection**") + + with st.expander("**For data that requires a device or equipment for collection or the context of the experiment, answer the following additional questions or provide relevant information based on the device or context that is used (for example)**", expanded=False): + st.write('''Data is collected on iPads (9th or 10th generation), iPad Air (5th generation) using an Avid AE-36 microphone and an Apple dongle to connect it to the iPad.''') + + st.subheader("**Challenge in tests and confounding factors**") + + with st.expander("**Which factors in the data might limit the generalization of potentially derived models? Is this information available as auxiliary labels for challenge tests? For instance:**", expanded=False): + st.write(''' + **a. Number and diversity of devices included in the dataset.** + + Distinct iPad devices were used at each site. + + **b. Data recording specificities, e.g., the view for a chest x-ray image.** + + The data were recorded with a head mounted headset with a microphone that could be at slightly different distances. The clinical diagnosis, depending on the disorder, was performed by one clinician or based on an EHR record or prescription. + + **c. Number and diversity of recording sites included in the dataset.** + + There are 5 recording sites included in the dataset. + + **d. Distribution shifts over time.** + + Changes in diagnostic criteria or practices could be a source of distribution shift. + ''') + + with st.expander("**What confounding factors might be present in the data?**", expanded=False): + st.write('''Noise artifacts, variations in diagnostic practices, inaccurate questionnaire responses, under reporting.''') + + with st.expander("**What confounding factors might be present in the data?**", expanded=False): + st.write(''' + Noise artifacts, variations in diagnostic practices, inaccurate questionnaire responses, under reporting. + + **a. Interactions between demographic or historically marginalized groups and data recordings, e.g., were women patients recorded in one site, and men in another?** + + Groups that have less trust in the medical system, AI, or are less proximal to the collection sites would have been less likely to be recruited. + + **b. Interactions between the labels and data recordings, e.g. were healthy patients recorded on one device and diseased patients on another?** + + Participants were screened for different disorders based on site, so they also had their data collected with different devices. + ''') + + st.subheader("**Collection and use of demographic information**") + + with st.expander("**Does the dataset identify any demographic sub-populations (e.g., by age, gender, sex, ethnicity)?**", expanded=False): + st.write('''Age, Gender, Sex, Ethnicity, Socioeconomic status''') + + st.subheader("**Pre-processing / de-identification**") + + with st.expander("**Was there any pre-processing for the de-identification of the patients? Provide the answer for the preliminary and the current version of the dataset.**", expanded=False): + st.write('''Yes, the data were extracted from the raw audio to limit re-identification and only the extracted features are being released with the dataset.''') + + with st.expander("**Was there any pre-processing for cleaning the data? Provide the answer for the preliminary and the current version of the dataset.**", expanded=False): + st.write('''No''') + + with st.expander("**Was the “raw” data (post de-identification) saved in addition to the preprocessed/cleaned data (e.g., to support unanticipated future uses)? If so, please provide a link or other access point to the “raw” data.**", expanded=False): + st.write('''Yes, it is saved and is not accessible publicly.''') + + with st.expander("**Were instances excluded from the dataset at the time of preprocessing? If so, why? For example, instances related to patients under 18 might be discarded.**", expanded=False): + st.write('''No''') + + st.subheader("**Labeling and subjectivity of labeling**") + + st.write('''**Is there an explicit label or target associated with each data instance? Please respond for both the preliminary dataset and the current version.**''') + + with st.expander('''**a. If yes: + - What are the labels provided? + - Who performed the labeling? For example, was the labeling done by a clinician, ML researcher, university or hospital?**''', expanded=False): + st.write('''Diagnostic labels are the result of a clinical assessment of the participant. At each site, a local clinician provided the diagnosis based on a clinical interview and appropriate work-up. For the psychiatric disorders cohort, this assessment was determined by using the participants EHR record or using an active prescription, which was done outside of data collection by an appropriately licensed clinician.''') + + with st.expander('''**b. What labeling strategy was used?**''', expanded=False): + st.write('''Gold standard label available in the data (diagnosed by a clinician).''') + + with st.expander('''**c. Human-labeled data: + - How many labelers were considered?**''', expanded=False): + st.write('''Single labeler per data + • What is the demographic of the labelers? (countries of residence, of origin, number of years of experience, age, gender, race, ethnicity, etc.) + Typically, the clinician at site of data collection, or external to (for prior diagnostic assessment) + • What guidelines did they follow? + Per Bridge2AI Protocols and ICD-10 codes. + • How many labelers provide a label per instance? + 1 + ''') + + with st.expander('''**What are the human-level performances in the applications that the dataset is supposed to address?**''', expanded=False): + st.write('''It varies greatly''') + + with st.expander('''**Is the software used to preprocess/clean/label the instances available? If so, please provide a link or other access point.**''', expanded=False): + st.write('''Yes. [https://github.com/sensein/b2aiprep](https://github.com/sensein/b2aiprep), [https://github.com/sensein/senselab](https://github.com/sensein/senselab)''') + + with st.expander('''**Is there any guideline that the future researchers are recommended to follow when creating new labels/defining new tasks?**''', expanded=False): + st.write('''The process for any new labels should be described alongside any release of a model or publication. This process should include exact variables used for this determination.''') + + st.subheader("**Collection Process**") + + with st.expander('''**Were any REB/IRB approval (e.g., by an institutional review board or research ethics board) received? If so, please provide a description of these review processes, including the outcomes, as well as a link or other access point to any supporting documentation.**''', expanded=False): + st.write('''Yes''') + + with st.expander('''**How was the data associated with each instance acquired? Was the data directly observable (e.g., medical images, labs, or vitals), reported by subjects (e.g., survey responses, pain levels, itching/burning sensations), or indirectly inferred/derived from other data (e.g., part-of-speech tags, model-based guesses for age or language)? If data was reported by subjects or indirectly inferred/derived from other data, was the data validated/verified? If so, please describe how.**''', expanded=False): + st.write('''The data was directly observable and reported by subjects. Clinical diagnoses were verified by clinicians reviewing audio and/or imaging data, looking at electronic health records, or medication prescriptions.''') + + with st.expander('''**What mechanisms or procedures were used to collect the data (e.g., hardware apparatus or sensor, manual human curation, software program, software API)? How were these mechanisms or procedures validated? Provide the answer for all modalities and collected data. Has this information been changed through the process? If so, explain why.**''', expanded=False): + st.write('''The data has been collected on an iPad app.''') + + with st.expander('''**Who was involved in the data collection process (e.g., patients, clinicians, doctors, ML researchers, hospital staff, vendors, etc.) and how were they compensated (e.g., how much were contributors paid)?**''', expanded=False): + st.write('''Research teams, which may include medical, graduate, or undergraduate students, coordinated with clinicians/doctors to identify appropriate participants. These clinicians and doctors were listed under IRB as co-investigators, and were added to the consortium, so that that their names are to be included on consortium-level publications that emerge from the research. Hospital staff were not involved in scheduling but assisted in the logistics of coordinating data collection. Participants were compensated for their time through electronic gift cards. Participants currently receive $40 for a data collection session that takes less than 90 minutes, and $80 for a session that takes over 90 minutes, for no more than a total of 3 sessions and maximum compensation of $120.''') + + with st.expander('''**Over what timeframe was the data collected?**''', expanded=False): + st.write('''The data was collected over a period of 12 months.''') + + with st.expander('''**Does the dataset relate to people?**''', expanded=False): + st.write('''Yes''') + + with st.expander('''**Did you collect the data from the individuals in question directly, or obtain it via third parties or other sources (e.g., hospitals, app company)?**''', expanded=False): + st.write('''Directly''') + + with st.expander('''**Were the individuals in question notified about the data collection?**''', expanded=False): + st.write('''Yes, participants went through an IRB-approved consent process.''') + + with st.expander('''**Did the individuals in question consent to the collection and use of their data?**''', expanded=False): + st.write('''Yes, all participants have been duly informed and agreed to the collection and the use of their data via prospective informed consent.''') + + with st.expander('''**If consent was obtained, were the consenting individuals provided with a mechanism to revoke their consent in the future or for certain uses?**''', expanded=False): + st.write('''Consenting participants are informed that they may withdraw from the study at any point. If a participant chooses to withdraw during or before the voice data collection, their data will not be included in the database. Participants are informed that research data (including voice recordings) cannot be removed from the database once the voice data collection process is completed.''') + + with st.expander('''**In which countries was the data collected?**''', expanded=False): + st.write('''USA and Canada''') + + with st.expander('''**Has an analysis of the potential impact of the dataset and its use on data subjects been conducted?**''', expanded=False): + st.write('''No''') + + st.subheader("**Inclusion Criteria-Accessibility in data collection**") + + with st.expander('''**Is there any language-based communication with patients (e.g.: English, French)? If yes, describe the choices of language(s) for communication. (for example, if there is an app used for communication, what are the language options?) English language was used for communication with study participants.**''', expanded=False): + st.write('''The only language option for v1.0.0 is English. Spanish versions of the protocol are under development.''') + + with st.expander('''**What are the accessibility measurements and what aspects were considered when the study was designed and implemented?**''', expanded=False): + st.write('''The protocol asks about disabilities. Collection accessibility was facilitated through the normal means of the collection sites, including reading questions to participants when needed.''') + + st.subheader("**Uses**") + + with st.expander('''**Has the dataset been used for any tasks already? If so, please provide a description.**''', expanded=False): + st.write('''A restricted version of the dataset containing raw audio has been used in the Bridge2AI Summer School and hackathon.''') + + with st.expander('''**Does using the dataset require the citation of the paper or any other forms of acknowledgement? If yes, is it easily accessible through google scholar or other repositories**''', expanded=False): + st.write('''>Bensoussan, Yael, et al. "Developing Multi-Disorder Voice Protocols: A team science approach involving clinical expertise, bioethics, standards, and DEI." Proc. Interspeech 2024. 2024. [https://www.isca-archive.org/interspeech_2024/bensoussan24_interspeech.html](https://www.isca-archive.org/interspeech_2024/bensoussan24_interspeech.html)''') + + with st.expander('''**Is there a repository that links to any or all papers or systems that use the dataset? If so, please provide a link or other access point. (besides Google scholar)**''', expanded=False): + st.write('''No''') + + with st.expander('''**Is there anything about the composition of the dataset or the way it was collected and preprocessed/cleaned/labeled that might impact future uses? For example, is there anything that a future user might need to know to avoid uses that could result in unfair treatment of individuals or groups (e.g., stereotyping, quality of service issues) or other undesirable harms (e.g., financial harms, legal risks) If so, please provide a description. Is there anything a future user could do to mitigate these undesirable harms?**''', expanded=False): + st.write('''Yes, this dataset has skews based on disorder category, site, and other demographic factors. Users should consider the multivariate distribution when assessing utility for different questions.''') + + with st.expander('''**Are there tasks for which the dataset should not be used? If so, please provide a description.**''', expanded=False): + st.write('''Yes, there are certain applications that are discouraged from using this dataset. Specifically, the dataset should not be used for non-clinical applications such as hiring decisions, insurance premium adjustments, or any form of surveillance that could lead to discrimination or harm. These discouraged uses are intended to prevent unethical or biased outcomes that could negatively impact individuals based on their health conditions or voice characteristics. The dataset is intended strictly for research that prioritize patient safety, privacy, and ethical use.''') + + st.subheader("**Dataset Distribution**") + + with st.expander('''**Will the dataset be distributed to third parties outside of the entity (e.g., company, institution, organization) on behalf of which the dataset was created?**''', expanded=False): + st.write('''The dataset will be distributed broadly to individuals outside of the entity who created the dataset.''') + + with st.expander('''**How will the dataset be distributed (e.g., tarball on website, API, GitHub)? Does the dataset have a digital object identifier (DOI)?**''', expanded=False): + st.write('''The dataset will be distributed through a data publishing platform accessible at [https://healthdatanexus.ai/](https://healthdatanexus.ai/) + + This platform provides publicly accessible metadata regarding the dataset with a DOI for persistent resolution. The dataset itself requires registered access.''') + + with st.expander('''**When was/will the dataset be distributed?**''', expanded=False): + st.write('''The data was published and made available at the end of November, 2024.''') + + with st.expander('''**Assuming the dataset is available, will it be/is the dataset distributed under a copyright or other intellectual property (IP) license, and/or under applicable terms of use (ToU)? If so, please describe this license and/or ToU, and provide a link or other access point to, or otherwise reproduce, any relevant licensing terms or ToU, as well as any fees associated with these restrictions.**''', expanded=False): + st.write(''' + Users of the dataset must agree to terms laid out in the registered access agreement. The terms relating to intellectual property are repeated here for informational purposes only: + + INTELLECTUAL PROPERTY RIGHTS. You understand and acknowledge that the Data may be protected by copyright and other rights, including other intellectual property rights. Duplication, as reasonably required to carry out Your Research Project with the Data, is nonetheless permitted. Sale of all or part of the Data on any media is not permitted. You recognize that nothing in this Agreement shall operate to transfer to You any intellectual property rights in or relating to the Data. You agree not to make intellectual property claims on the Data. You agree not to use intellectual property protection in ways that would prevent or block access to, or use of, any element of these Data, or conclusions drawn directly from the Data. You can elect to perform further research that would add intellectual and resource capital to the Data and decide to obtain intellectual property rights on these downstream discoveries. You agree to implement licensing policies that will not obstruct further research. You agree to respect the Fort Lauderdale Agreement. + + There are no fees associated with these restrictions. + + ''') + + with st.expander('''**Have any third parties imposed IP-based or other restrictions on the data associated with the instances? If so, please describe these restrictions, and provide a link or other access point to, or otherwise reproduce, any relevant licensing terms, as well as any fees associated with these restrictions.**''', expanded=False): + st.write('''No IP-based restrictions have been imposed by third parties.''') + + with st.expander('''**Do any export controls or other regulatory restrictions apply to the dataset or to individual instances? If so, please describe these restrictions, and provide a link or other access point to, or otherwise reproduce, any supporting documentation.**''', expanded=False): + st.write('''No export controls apply to the dataset.''') + + st.subheader("**Maintenance**") + + with st.expander('''**Who is supporting/hosting/maintaining the dataset?**''', expanded=False): + st.write('''The dataset is supported by the NIH via the Bridge2AI project. + The dataset is hosted by the [Health Data Nexus](https://healthdatanexus.ai/), a data publishing platform maintained by the Temerty Center for Artificial Intelligence Research and Education in Medicine (T-CAIREM) based at the University of Toronto. The Health Data Nexus maintains the technical infrastructure hosting dataset and provides continued access to interested researchers. + ''') + + with st.expander('''**How can the owner/curator/manager of the dataset be contacted (e.g. email address)?**''', expanded=False): + st.write('''The platform team may be contacted through: contact@healthdatanexus.ai + The curator of the data may be contacted through: info@b2ai-voice.org + ''') + + with st.expander('''**Is there an erratum? If so, please provide a link or other access point.**''', expanded=False): + st.write('''There is no erratum. A changelog for each dataset version is published online with the dataset metadata.''') + + with st.expander('''**Will the dataset be updated (e.g., to correct labeling errors, add new instances, delete instances)? If so, please describe how often, by whom, and how updates will be communicated to users (e.g., mailing list, GitHub)?**''', expanded=False): + st.write('''Yes, further versions of the dataset will be released on a semi-annual (twice a year). These updates will be distributed as new versions of the dataset on the Health Data Nexus platform. Users will be notified through news items on the platform as well as through standard communication channels.''') + + with st.expander('''**If the dataset relates to people, are there applicable limits on the retention of the data associated with the instances (e.g., were individuals in question told that their data would be retained for a fixed period of time and then deleted)? If so, please describe these limits and explain how they will be enforced.**''', expanded=False): + st.write('''Once data is contributed, the data will be retained as long as it is useful for research purposes, possibly indefinitely.''') + + with st.expander('''**Will older versions of the dataset continue to be supported/hosted/maintained? If so, please describe how and for how long. If not, please describe how its obsolescence will be communicated to users.**''', expanded=False): + st.write('''By default, older versions of the dataset will continue to be supported, hosted, and made available to researchers. Each version of the dataset has a unique DOI. The dataset publishers reserve the right to remove access to older versions.''') + + with st.expander('''**If others want to extend/augment/build on/contribute to the dataset, is there a mechanism for them to do so?**''', expanded=False): + st.write('''For dataset extensions and augmentations, it is possible for others to publish a derivative dataset on the Health Data Nexus which references the original source. These derivative datasets may be made available under the same conditions as the source data. + For augmentations to the code used to produce the data, the open-source repositories have discussion forums and issue pages which allow for public discussion of data preprocessing. The repository also has a mechanism (“pull requests”) for contributing improvements to the data preprocessing code. + ''') \ No newline at end of file From fd45f3673361d1891d1829d25830f1c33f29491a Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Thu, 21 Nov 2024 10:35:19 -0500 Subject: [PATCH 15/18] B2AI-542 --- src/tabs/healthsheet.py | 149 ++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 96 deletions(-) diff --git a/src/tabs/healthsheet.py b/src/tabs/healthsheet.py index cd5935c..2411138 100644 --- a/src/tabs/healthsheet.py +++ b/src/tabs/healthsheet.py @@ -38,18 +38,17 @@ def healthsheet_page(tab_name): st.write('''Voice as a Biomarker of Health is being co-led by Dr Yaël Bensoussan, MD, MSc from USF Health Morsani College of Medicine and Olivier Elemento, PhD from Weill Cornell Medicine, who are co-principal investigators for the project, which is funded by the NIH Common Fund within the Bridge2AI Program. The project also includes lead investigators from 10 other universities in North America; Alexandros Sigaras, MSc and Anaïs Rameau, MD, MPhil (Weill Cornell Medicine), Maria Powell, CCC-SLP, PhD (Vanderbilt University Medical Center), Ruth Bahr, CCC-SLP, PhD (USF Health Morsani College of Medicine), Jennifer Sui, MD (Hospital for Sick Children), Philip Payne, PhD (Washington University in St. Louis), David Dorr, MD (Oregon Health & Science University), Jean-Christophe Bélisle-Pipon, PhD (Simon Fraser University), Vardit Ravitsky , PhD (The Hastings Center), Satrajit Ghosh, PhD (Massachusetts Institute of Technology), Frank Rudzizc, PhD (University of Toronto), Jordan Lerner-Ellis, PhD (Sinai Health) and Don Bolser, PhD (University of Florida).There are over 50 other investigators, clinicians, scholars and trainees who have contributed to the development of this dataset. Please see full list of collaborators here: [The Bridge2AI-Voice Consortium (2024)](https://b2ai-voice.org/wp-content/uploads/2024/11/FOR-WEBSITE-Year-2-Bridge2AI-Voice-Consortium-Authors.docx)''') with st.expander("**Who funded the creation of the dataset? If there is an associated grant, please provide the name of the grantor and the grant name and number. If the funding institution differs from the research organization creating and managing the dataset, please state how.**", expanded=False): - st.write('''The NIH Common Fund - [3TF- OT2ActfOD032720Projectf01S1](https://reporter.nih.gov/search/ES3d7yibyESXrX-rp6g1Ng/project-details/10858564)''') + st.write('''The NIH Common Fund
    [3TF- OT2ActfOD032720Projectf01S1](https://reporter.nih.gov/search/ES3d7yibyESXrX-rp6g1Ng/project-details/10858564)''', unsafe_allow_html=True) with st.expander("**What is the distribution of backgrounds and experience/expertise of the dataset curators/generators?**", expanded=False): st.write('''The curators and generators of the Bridge2AI Voice dataset come from a diverse range of backgrounds and areas of expertise, reflecting the interdisciplinary nature of the project. The team includes: - 1. Clinicians and Healthcare Professionals: Practicing doctors and healthcare workers involved in the direct collection of clinical data and providing practical insights into the medical relevance of the dataset. - 2. Biomedical Researchers: Experts in clinical medicine, neurology, and psychiatry, contributing deep knowledge of the medical conditions being studied. - 3. Machine Learning and AI Specialists: Researchers and engineers with expertise in machine learning, artificial intelligence, and data science, focusing on developing models and algorithms for analyzing voice data. - 4. Data Scientists and Statisticians: Professionals skilled in data curation, preprocessing, and statistical analysis, ensuring the dataset is robust and suitable for machine learning applications. - 5. Social Scientists and Ethicists: Experts in ethics, sociology, and human subjects research, ensuring the dataset is ethically sourced and meets standards for privacy and consent. - 6. Engineers and Technologists: Individuals with experience in software development, systems engineering, and data infrastructure, contributing to the technical aspects of data collection, storage, and dissemination. - ''') +1. Clinicians and Healthcare Professionals: Practicing doctors and healthcare workers involved in the direct collection of clinical data and providing practical insights into the medical relevance of the dataset. +2. Biomedical Researchers: Experts in clinical medicine, neurology, and psychiatry, contributing deep knowledge of the medical conditions being studied. +3. Machine Learning and AI Specialists: Researchers and engineers with expertise in machine learning, artificial intelligence, and data science, focusing on developing models and algorithms for analyzing voice data. +4. Data Scientists and Statisticians: Professionals skilled in data curation, preprocessing, and statistical analysis, ensuring the dataset is robust and suitable for machine learning applications. +5. Social Scientists and Ethicists: Experts in ethics, sociology, and human subjects research, ensuring the dataset is ethically sourced and meets standards for privacy and consent. +6. Engineers and Technologists: Individuals with experience in software development, systems engineering, and data infrastructure, contributing to the technical aspects of data collection, storage, and dissemination. +''', unsafe_allow_html=True) st.subheader("**Data Composition**") @@ -85,18 +84,10 @@ def healthsheet_page(tab_name): with st.expander("**Is the dataset self-contained, or does it link to or otherwise rely on external resources (e.g., websites, other datasets)? If it links to or relies on external resources:**", expanded=False): st.write(''' - **a. Are there guarantees that they will exist, and remain constant, over time?** - - NA - - **b. Are there official archival versions of the complete dataset (i.e., including the external resources as they existed at the time the dataset was created)?** - - NA - - **c. Are there any restrictions (e.g., licenses, fees) associated with any of the external resources that might apply to a future user? Please provide descriptions of all external resources and any restrictions associated with them, as well as links or other access points, as appropriate.** - - It is self-contained. - ''') + **a. Are there guarantees that they will exist, and remain constant, over time?**
    NA
    + **b. Are there official archival versions of the complete dataset (i.e., including the external resources as they existed at the time the dataset was created)?**
    NA
    + **c. Are there any restrictions (e.g., licenses, fees) associated with any of the external resources that might apply to a future user? Please provide descriptions of all external resources and any restrictions associated with them, as well as links or other access points, as appropriate.**
    It is self-contained. + ''', unsafe_allow_html=True) with st.expander("**Does the dataset contain data that might be considered confidential (e.g., data that is protected by legal privilege or by doctor-patient confidentiality, data that includes the content of individuals' non-public communications that is confidential)? If so, please provide a description.**", expanded=False): st.write('''No''') @@ -108,15 +99,9 @@ def healthsheet_page(tab_name): st.write('''This dataset has been deidentified through removal of all audio data and certain sensitive fields identified by a team of ethicists.''') with st.expander("**Does the dataset contain data that might be considered sensitive in any way (e.g., data that reveals racial or ethnic origins, sexual orientations, religious beliefs, political opinions or union memberships, or locations; financial or health data; biometric or genetic data; forms of government identification, such as social security numbers; criminal history)? If so, please provide a description.**", expanded=False): - st.write(''' - Yes: - - **racial or ethnic origins**: The dataset includes race information. - - **sexual orientations**: The dataset includes sexual orientation information. - - **financial or health data**: The dataset includes socioeconomic and health information. - ''') + st.write('''Yes:
    racial or ethnic origins: The dataset includes race information.
    + sexual orientations: The dataset includes sexual orientation information.
    + financial or health data: The dataset includes socioeconomic and health information.''', unsafe_allow_html=True) st.subheader("**Devices and Contextual Attributes in Data Collection**") @@ -126,39 +111,18 @@ def healthsheet_page(tab_name): st.subheader("**Challenge in tests and confounding factors**") with st.expander("**Which factors in the data might limit the generalization of potentially derived models? Is this information available as auxiliary labels for challenge tests? For instance:**", expanded=False): - st.write(''' - **a. Number and diversity of devices included in the dataset.** - - Distinct iPad devices were used at each site. - - **b. Data recording specificities, e.g., the view for a chest x-ray image.** - - The data were recorded with a head mounted headset with a microphone that could be at slightly different distances. The clinical diagnosis, depending on the disorder, was performed by one clinician or based on an EHR record or prescription. - - **c. Number and diversity of recording sites included in the dataset.** - - There are 5 recording sites included in the dataset. - - **d. Distribution shifts over time.** - - Changes in diagnostic criteria or practices could be a source of distribution shift. - ''') + st.write('''**a. Number and diversity of devices included in the dataset.**
    Distinct iPad devices were used at each site.
    + **b. Data recording specificities, e.g., the view for a chest x-ray image.**
    The data were recorded with a head mounted headset with a microphone that could be at slightly different distances. The clinical diagnosis, depending on the disorder, was performed by one clinician or based on an EHR record or prescription.
    + **c. Number and diversity of recording sites included in the dataset.**
    There are 5 recording sites included in the dataset.
    + **d. Distribution shifts over time.**
    Changes in diagnostic criteria or practices could be a source of distribution shift.''', unsafe_allow_html=True) with st.expander("**What confounding factors might be present in the data?**", expanded=False): st.write('''Noise artifacts, variations in diagnostic practices, inaccurate questionnaire responses, under reporting.''') with st.expander("**What confounding factors might be present in the data?**", expanded=False): - st.write(''' - Noise artifacts, variations in diagnostic practices, inaccurate questionnaire responses, under reporting. - - **a. Interactions between demographic or historically marginalized groups and data recordings, e.g., were women patients recorded in one site, and men in another?** - - Groups that have less trust in the medical system, AI, or are less proximal to the collection sites would have been less likely to be recruited. - - **b. Interactions between the labels and data recordings, e.g. were healthy patients recorded on one device and diseased patients on another?** - - Participants were screened for different disorders based on site, so they also had their data collected with different devices. - ''') + st.write('''Noise artifacts, variations in diagnostic practices, inaccurate questionnaire responses, under reporting.
    + **a. Interactions between demographic or historically marginalized groups and data recordings, e.g., were women patients recorded in one site, and men in another?**
    Groups that have less trust in the medical system, AI, or are less proximal to the collection sites would have been less likely to be recruited.
    + **b. Interactions between the labels and data recordings, e.g. were healthy patients recorded on one device and diseased patients on another?**
    Participants were screened for different disorders based on site, so they also had their data collected with different devices.''', unsafe_allow_html=True) st.subheader("**Collection and use of demographic information**") @@ -181,26 +145,23 @@ def healthsheet_page(tab_name): st.subheader("**Labeling and subjectivity of labeling**") - st.write('''**Is there an explicit label or target associated with each data instance? Please respond for both the preliminary dataset and the current version.**''') - - with st.expander('''**a. If yes: - - What are the labels provided? - - Who performed the labeling? For example, was the labeling done by a clinician, ML researcher, university or hospital?**''', expanded=False): - st.write('''Diagnostic labels are the result of a clinical assessment of the participant. At each site, a local clinician provided the diagnosis based on a clinical interview and appropriate work-up. For the psychiatric disorders cohort, this assessment was determined by using the participants EHR record or using an active prescription, which was done outside of data collection by an appropriately licensed clinician.''') - - with st.expander('''**b. What labeling strategy was used?**''', expanded=False): - st.write('''Gold standard label available in the data (diagnosed by a clinician).''') - - with st.expander('''**c. Human-labeled data: - - How many labelers were considered?**''', expanded=False): - st.write('''Single labeler per data - • What is the demographic of the labelers? (countries of residence, of origin, number of years of experience, age, gender, race, ethnicity, etc.) - Typically, the clinician at site of data collection, or external to (for prior diagnostic assessment) - • What guidelines did they follow? - Per Bridge2AI Protocols and ICD-10 codes. - • How many labelers provide a label per instance? - 1 - ''') + with st.expander('''**Is there an explicit label or target associated with each data instance? Please respond for both the preliminary dataset and the current version.**''', expanded=False): + st.write('''a. If yes:
    +
      +
    • What are the labels provided?
    • +
    • Who performed the labeling? For example, was the labeling done by a clinician, ML researcher, university or hospital?
    • +
    +Diagnostic labels are the result of a clinical assessment of the participant. At each site, a local clinician provided the diagnosis based on a clinical interview and appropriate work-up. For the psychiatric disorders cohort, this assessment was determined by using the participants EHR record or using an active prescription, which was done outside of data collection by an appropriately licensed clinician. +
    +b. What labeling strategy was used?
    +Gold standard label available in the data (diagnosed by a clinician).
    +c. Human-labeled data:
    +
      +
    • How many labelers were considered?
      Single labeler per data
    • +
    • What is the demographic of the labelers? (countries of residence, of origin, number of years of experience, age, gender, race, ethnicity, etc.)
      Typically, the clinician at site of data collection, or external to (for prior diagnostic assessment)
    • +
    • What guidelines did they follow?
      Per Bridge2AI Protocols and ICD-10 codes.
    • +
    • How many labelers provide a label per instance?
      1
    • +
    ''', unsafe_allow_html=True) with st.expander('''**What are the human-level performances in the applications that the dataset is supposed to address?**''', expanded=False): st.write('''It varies greatly''') @@ -223,7 +184,8 @@ def healthsheet_page(tab_name): st.write('''The data has been collected on an iPad app.''') with st.expander('''**Who was involved in the data collection process (e.g., patients, clinicians, doctors, ML researchers, hospital staff, vendors, etc.) and how were they compensated (e.g., how much were contributors paid)?**''', expanded=False): - st.write('''Research teams, which may include medical, graduate, or undergraduate students, coordinated with clinicians/doctors to identify appropriate participants. These clinicians and doctors were listed under IRB as co-investigators, and were added to the consortium, so that that their names are to be included on consortium-level publications that emerge from the research. Hospital staff were not involved in scheduling but assisted in the logistics of coordinating data collection. Participants were compensated for their time through electronic gift cards. Participants currently receive $40 for a data collection session that takes less than 90 minutes, and $80 for a session that takes over 90 minutes, for no more than a total of 3 sessions and maximum compensation of $120.''') + st.write('''Research teams, which may include medical, graduate, or undergraduate students, coordinated with clinicians/doctors to identify appropriate participants. These clinicians and doctors were listed under IRB as co-investigators, and were added to the consortium, so that that their names are to be included on consortium-level publications that emerge from the research. Hospital staff were not involved in scheduling but assisted in the logistics of coordinating data collection. +

    Participants were compensated for their time through electronic gift cards. Participants currently receive \$40 for a data collection session that takes less than 90 minutes, and \$80 for a session that takes over 90 minutes, for no more than a total of 3 sessions and maximum compensation of \$120.''', unsafe_allow_html=True) with st.expander('''**Over what timeframe was the data collected?**''', expanded=False): st.write('''The data was collected over a period of 12 months.''') @@ -251,8 +213,8 @@ def healthsheet_page(tab_name): st.subheader("**Inclusion Criteria-Accessibility in data collection**") - with st.expander('''**Is there any language-based communication with patients (e.g.: English, French)? If yes, describe the choices of language(s) for communication. (for example, if there is an app used for communication, what are the language options?) English language was used for communication with study participants.**''', expanded=False): - st.write('''The only language option for v1.0.0 is English. Spanish versions of the protocol are under development.''') + with st.expander('''**Is there any language-based communication with patients (e.g.: English, French)? If yes, describe the choices of language(s) for communication. (for example, if there is an app used for communication, what are the language options?)**''', expanded=False): + st.write('''English language was used for communication with study participants.
    The only language option for v1.0.0 is English. Spanish versions of the protocol are under development.''', unsafe_allow_html=True) with st.expander('''**What are the accessibility measurements and what aspects were considered when the study was designed and implemented?**''', expanded=False): st.write('''The protocol asks about disabilities. Collection accessibility was facilitated through the normal means of the collection sites, including reading questions to participants when needed.''') @@ -280,9 +242,8 @@ def healthsheet_page(tab_name): st.write('''The dataset will be distributed broadly to individuals outside of the entity who created the dataset.''') with st.expander('''**How will the dataset be distributed (e.g., tarball on website, API, GitHub)? Does the dataset have a digital object identifier (DOI)?**''', expanded=False): - st.write('''The dataset will be distributed through a data publishing platform accessible at [https://healthdatanexus.ai/](https://healthdatanexus.ai/) - - This platform provides publicly accessible metadata regarding the dataset with a DOI for persistent resolution. The dataset itself requires registered access.''') + st.write('''The dataset will be distributed through a data publishing platform accessible at [https://healthdatanexus.ai/](https://healthdatanexus.ai/)

    + This platform provides publicly accessible metadata regarding the dataset with a DOI for persistent resolution. The dataset itself requires registered access.''', unsafe_allow_html=True) with st.expander('''**When was/will the dataset be distributed?**''', expanded=False): st.write('''The data was published and made available at the end of November, 2024.''') @@ -291,11 +252,9 @@ def healthsheet_page(tab_name): st.write(''' Users of the dataset must agree to terms laid out in the registered access agreement. The terms relating to intellectual property are repeated here for informational purposes only: - INTELLECTUAL PROPERTY RIGHTS. You understand and acknowledge that the Data may be protected by copyright and other rights, including other intellectual property rights. Duplication, as reasonably required to carry out Your Research Project with the Data, is nonetheless permitted. Sale of all or part of the Data on any media is not permitted. You recognize that nothing in this Agreement shall operate to transfer to You any intellectual property rights in or relating to the Data. You agree not to make intellectual property claims on the Data. You agree not to use intellectual property protection in ways that would prevent or block access to, or use of, any element of these Data, or conclusions drawn directly from the Data. You can elect to perform further research that would add intellectual and resource capital to the Data and decide to obtain intellectual property rights on these downstream discoveries. You agree to implement licensing policies that will not obstruct further research. You agree to respect the Fort Lauderdale Agreement. - - There are no fees associated with these restrictions. +

    INTELLECTUAL PROPERTY RIGHTS. You understand and acknowledge that the Data may be protected by copyright and other rights, including other intellectual property rights. Duplication, as reasonably required to carry out Your Research Project with the Data, is nonetheless permitted. Sale of all or part of the Data on any media is not permitted. You recognize that nothing in this Agreement shall operate to transfer to You any intellectual property rights in or relating to the Data. You agree not to make intellectual property claims on the Data. You agree not to use intellectual property protection in ways that would prevent or block access to, or use of, any element of these Data, or conclusions drawn directly from the Data. You can elect to perform further research that would add intellectual and resource capital to the Data and decide to obtain intellectual property rights on these downstream discoveries. You agree to implement licensing policies that will not obstruct further research. You agree to respect the Fort Lauderdale Agreement.

    - ''') + There are no fees associated with these restrictions.''', unsafe_allow_html=True) with st.expander('''**Have any third parties imposed IP-based or other restrictions on the data associated with the instances? If so, please describe these restrictions, and provide a link or other access point to, or otherwise reproduce, any relevant licensing terms, as well as any fees associated with these restrictions.**''', expanded=False): st.write('''No IP-based restrictions have been imposed by third parties.''') @@ -306,14 +265,13 @@ def healthsheet_page(tab_name): st.subheader("**Maintenance**") with st.expander('''**Who is supporting/hosting/maintaining the dataset?**''', expanded=False): - st.write('''The dataset is supported by the NIH via the Bridge2AI project. + st.write('''The dataset is supported by the NIH via the Bridge2AI project.
    The dataset is hosted by the [Health Data Nexus](https://healthdatanexus.ai/), a data publishing platform maintained by the Temerty Center for Artificial Intelligence Research and Education in Medicine (T-CAIREM) based at the University of Toronto. The Health Data Nexus maintains the technical infrastructure hosting dataset and provides continued access to interested researchers. - ''') + ''', unsafe_allow_html=True) with st.expander('''**How can the owner/curator/manager of the dataset be contacted (e.g. email address)?**''', expanded=False): - st.write('''The platform team may be contacted through: contact@healthdatanexus.ai - The curator of the data may be contacted through: info@b2ai-voice.org - ''') + st.write('''The platform team may be contacted through: contact@healthdatanexus.ai
    + The curator of the data may be contacted through: info@b2ai-voice.org''', unsafe_allow_html=True) with st.expander('''**Is there an erratum? If so, please provide a link or other access point.**''', expanded=False): st.write('''There is no erratum. A changelog for each dataset version is published online with the dataset metadata.''') @@ -328,6 +286,5 @@ def healthsheet_page(tab_name): st.write('''By default, older versions of the dataset will continue to be supported, hosted, and made available to researchers. Each version of the dataset has a unique DOI. The dataset publishers reserve the right to remove access to older versions.''') with st.expander('''**If others want to extend/augment/build on/contribute to the dataset, is there a mechanism for them to do so?**''', expanded=False): - st.write('''For dataset extensions and augmentations, it is possible for others to publish a derivative dataset on the Health Data Nexus which references the original source. These derivative datasets may be made available under the same conditions as the source data. - For augmentations to the code used to produce the data, the open-source repositories have discussion forums and issue pages which allow for public discussion of data preprocessing. The repository also has a mechanism (“pull requests”) for contributing improvements to the data preprocessing code. - ''') \ No newline at end of file + st.write('''For dataset extensions and augmentations, it is possible for others to publish a derivative dataset on the Health Data Nexus which references the original source. These derivative datasets may be made available under the same conditions as the source data.

    + For augmentations to the code used to produce the data, the open-source repositories have discussion forums and issue pages which allow for public discussion of data preprocessing. The repository also has a mechanism (“pull requests”) for contributing improvements to the data preprocessing code.''', unsafe_allow_html=True) \ No newline at end of file From 66cb14106456bd769a3b71ef76de19d03b7b8711 Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Thu, 21 Nov 2024 11:30:53 -0500 Subject: [PATCH 16/18] B2AI-540 --- src/tabs/data_governance.py | 74 ++++++++++++++++++++++++++++++++++++- src/tabs/healthsheet.py | 28 +++++++------- 2 files changed, 86 insertions(+), 16 deletions(-) diff --git a/src/tabs/data_governance.py b/src/tabs/data_governance.py index aa2d7f0..8bc5d86 100644 --- a/src/tabs/data_governance.py +++ b/src/tabs/data_governance.py @@ -1,5 +1,75 @@ import streamlit as st -from tabs.utils import coming_soon_message def data_governance_page(tab_name): - coming_soon_message(tab_name) \ No newline at end of file + + st.write( + """ + Accessing the dataset requires several steps, through registered access governance, including:
    +
      +
    • Registration with confirmation of identity
    • +
    • Signing of the Bridge2AI-Voice Registered Access Agreement (data-use agreement) stipulating conditions of use for the data
    • +
    + """, unsafe_allow_html=True) + + st.write( + """[License](https://b2ai-voice.org/wp-content/uploads/2024/11/B2AI-Voice_Registered_Access_Data_Agreement_v20241119.pdf)""", unsafe_allow_html=False) + + st.header("Oversight") + + with st.expander('''**Has the clinical study has been reviewed and approved by at least one human subjects’ protection review board?**''', expanded=False): + st.write('''Submitted, approved by USF Single IRB and subsites IRB through the Single IRB Process''') + + with st.expander('''**Is this clinical study for a drug product?**''', expanded=False): + st.write('''No''') + + with st.expander('''**Is this clinical study for a medical device?**''', expanded=False): + st.write('''No''') + + with st.expander('''**Was a data monitoring committee appointed for this study?**''', expanded=False): + st.write('''No''') + + st.header("De-Identification Levels") + + st.write("""Level of de-identification from this dataset Identifiable information (under HIPAA and under the Common Rule) as well as data considered as sensitive have been removed from this dataset.""", unsafe_allow_html=False) + + with st.expander('''**Does this dataset remove direct identifiers?**''', expanded=False): + st.write('''Yes''') + + with st.expander('''**Does this dataset apply the HIPAA de-identification rules?**''', expanded=False): + st.write('''Yes''') + + with st.expander('''**Does this dataset rebase and/or replace dates by integers?**''', expanded=False): + st.write('''Yes''') + + with st.expander('''**Does this dataset remove narrative text fields?**''', expanded=False): + st.write('''Yes''') + + with st.expander('''**Does this dataset achieve K-anonymization (k>=2)?**''', expanded=False): + st.write('''No''') + + st.subheader("De-identification Details") + + st.write("""All direct identifiers were removed, as these would reveal the identity of the research participant. These include name, civic address, and social security numbers. Indirect identifiers were removed where these created a significant risk of causing participant re-identification, for example through their combination with other public data available on social media, in government registries, or elsewhere. These include select geographic or demographic identifiers, as well as some information about household composition or cultural identity. Non-identifying elements of data that revealed highly sensitive information, such as information about household income, mental health status, traumatic life experiences, and the like were also removed. All raw voice data was removed, as this data has the potential to cause to individual re-identification or to be used for illicit or unauthorized purposes. """, unsafe_allow_html=False) + + st.header("Consent") + + st.subheader("Consent Type", divider="violet") + + with st.expander('''**Does this dataset allow only the non-commercial use of the data?**''', expanded=False): + st.write('''No''') + + with st.expander('''**Does this dataset allow only the use of the data in a specific geographic location?**''', expanded=False): + st.write('''No''') + + with st.expander('''**Does this dataset allow only the use of the data for a specific type of research?**''', expanded=False): + st.write('''No''') + + with st.expander('''**Does this dataset allow only the use of the data for genetic research?**''', expanded=False): + st.write('''No''') + + with st.expander('''**Does this dataset allow only the use of the data for research that does not involve the development of methods or algorithms?**''', expanded=False): + st.write('''No''') + + st.subheader("Consent Details", divider="violet") + + st.write("""Research data that does not contain your direct identifiers will be shared with external researchers for future research through a secure database. Data that poses a low risk of causing individual re-identification will be shared in registered access with the general public. Data that would pose a heightened risk of re-identification if shared in full open access will be shared through a controlled access mechanism with authorized researchers.""", unsafe_allow_html=False) diff --git a/src/tabs/healthsheet.py b/src/tabs/healthsheet.py index 2411138..3eb7626 100644 --- a/src/tabs/healthsheet.py +++ b/src/tabs/healthsheet.py @@ -3,7 +3,7 @@ # Define the content of the Health Sheet page def healthsheet_page(tab_name): - st.subheader("**General Information**") + st.header("**General Information**") st.markdown(''' **Provide a 2-sentence summary of this dataset.** @@ -15,7 +15,7 @@ def healthsheet_page(tab_name): with st.expander("**Has the dataset been audited before? If yes, by whom and what are the results?**", expanded=False): st.write('''The dataset has been audited internally for missingness and consistency by the data release team. A missingness table is included with the dataset. Certain aspects of the data (e.g., transcription) were generated using off the shelf models that have not been audited for correctness.''') - st.subheader("**Dataset Versioning**") + st.header("**Dataset Versioning**") with st.expander("**Does the dataset get released as static versions or is it dynamically updated?**", expanded=False): st.write('''Static''') @@ -23,7 +23,7 @@ def healthsheet_page(tab_name): with st.expander("**Does the current version/subversion of the dataset come with predefined task(s), labels, and recommended data splits (e.g., for training, development/validation, testing)? If yes, please provide a high-level description of the introduced tasks, data splits, and labeling, and explain the rationale behind them. Please provide the related links and references. If not, is there any resource (website, portal, etc.) to keep track of all defined tasks and/or associated label definitions? (please note that more detailed questions w.r.t labeling is provided in further sections)**", expanded=False): st.write('''Yes, the current version of the dataset comes with predefined tasks and labeling. The tasks are primarily designed for training machine-learning models for disease detection and classification using voice data. Labels include diagnostic categories such as vocal pathologies, neurological disorders, psychiatric conditions, and respiratory disorders. However, there are no predefined recommended data splits for training, validation, or testing. Researchers are encouraged to create their own data splits based on their specific requirements. More details regarding task definitions and labeling can be found in the dataset.''') - st.subheader("**Motivation**") + st.header("**Motivation**") with st.expander("**For what purpose was the dataset created? Was there a specific task in mind? Was there a specific gap that needed to be filled? Please provide a description.**", expanded=False): st.write('''The Bridge2AI Voice dataset was created to address a gap in the availability of large-scale, diverse, and well-documented voice data for use in clinical machine-learning applications. Previous studies on machine learning-based voice diagnosis produced promising results, but their sample sizes were too small, or they lacked the key metadata needed for training robust, clinically useful models. The dataset aims to bridge this gap by providing an ethically sourced, large, and diverse dataset to develop, benchmark, or validate clinically applicable AI/ML models. The goal is to facilitate the use of voice as a non-invasive, cost-effective biomarker for the screening, diagnosis, and monitoring of a wide range of health conditions.''') @@ -50,7 +50,7 @@ def healthsheet_page(tab_name): 6. Engineers and Technologists: Individuals with experience in software development, systems engineering, and data infrastructure, contributing to the technical aspects of data collection, storage, and dissemination. ''', unsafe_allow_html=True) - st.subheader("**Data Composition**") + st.header("**Data Composition**") with st.expander("**What do the instances that comprise the dataset represent (e.g., documents, images, people, countries)? Are there multiple types of instances? Please provide a description.**", expanded=False): st.write('''Each instance represents a person.''') @@ -103,12 +103,12 @@ def healthsheet_page(tab_name): sexual orientations: The dataset includes sexual orientation information.
    financial or health data: The dataset includes socioeconomic and health information.''', unsafe_allow_html=True) - st.subheader("**Devices and Contextual Attributes in Data Collection**") + st.header("**Devices and Contextual Attributes in Data Collection**") with st.expander("**For data that requires a device or equipment for collection or the context of the experiment, answer the following additional questions or provide relevant information based on the device or context that is used (for example)**", expanded=False): st.write('''Data is collected on iPads (9th or 10th generation), iPad Air (5th generation) using an Avid AE-36 microphone and an Apple dongle to connect it to the iPad.''') - st.subheader("**Challenge in tests and confounding factors**") + st.header("**Challenge in tests and confounding factors**") with st.expander("**Which factors in the data might limit the generalization of potentially derived models? Is this information available as auxiliary labels for challenge tests? For instance:**", expanded=False): st.write('''**a. Number and diversity of devices included in the dataset.**
    Distinct iPad devices were used at each site.
    @@ -124,12 +124,12 @@ def healthsheet_page(tab_name): **a. Interactions between demographic or historically marginalized groups and data recordings, e.g., were women patients recorded in one site, and men in another?**
    Groups that have less trust in the medical system, AI, or are less proximal to the collection sites would have been less likely to be recruited.
    **b. Interactions between the labels and data recordings, e.g. were healthy patients recorded on one device and diseased patients on another?**
    Participants were screened for different disorders based on site, so they also had their data collected with different devices.''', unsafe_allow_html=True) - st.subheader("**Collection and use of demographic information**") + st.header("**Collection and use of demographic information**") with st.expander("**Does the dataset identify any demographic sub-populations (e.g., by age, gender, sex, ethnicity)?**", expanded=False): st.write('''Age, Gender, Sex, Ethnicity, Socioeconomic status''') - st.subheader("**Pre-processing / de-identification**") + st.header("**Pre-processing / de-identification**") with st.expander("**Was there any pre-processing for the de-identification of the patients? Provide the answer for the preliminary and the current version of the dataset.**", expanded=False): st.write('''Yes, the data were extracted from the raw audio to limit re-identification and only the extracted features are being released with the dataset.''') @@ -143,7 +143,7 @@ def healthsheet_page(tab_name): with st.expander("**Were instances excluded from the dataset at the time of preprocessing? If so, why? For example, instances related to patients under 18 might be discarded.**", expanded=False): st.write('''No''') - st.subheader("**Labeling and subjectivity of labeling**") + st.header("**Labeling and subjectivity of labeling**") with st.expander('''**Is there an explicit label or target associated with each data instance? Please respond for both the preliminary dataset and the current version.**''', expanded=False): st.write('''a. If yes:
    @@ -172,7 +172,7 @@ def healthsheet_page(tab_name): with st.expander('''**Is there any guideline that the future researchers are recommended to follow when creating new labels/defining new tasks?**''', expanded=False): st.write('''The process for any new labels should be described alongside any release of a model or publication. This process should include exact variables used for this determination.''') - st.subheader("**Collection Process**") + st.header("**Collection Process**") with st.expander('''**Were any REB/IRB approval (e.g., by an institutional review board or research ethics board) received? If so, please provide a description of these review processes, including the outcomes, as well as a link or other access point to any supporting documentation.**''', expanded=False): st.write('''Yes''') @@ -211,7 +211,7 @@ def healthsheet_page(tab_name): with st.expander('''**Has an analysis of the potential impact of the dataset and its use on data subjects been conducted?**''', expanded=False): st.write('''No''') - st.subheader("**Inclusion Criteria-Accessibility in data collection**") + st.header("**Inclusion Criteria-Accessibility in data collection**") with st.expander('''**Is there any language-based communication with patients (e.g.: English, French)? If yes, describe the choices of language(s) for communication. (for example, if there is an app used for communication, what are the language options?)**''', expanded=False): st.write('''English language was used for communication with study participants.
    The only language option for v1.0.0 is English. Spanish versions of the protocol are under development.''', unsafe_allow_html=True) @@ -219,7 +219,7 @@ def healthsheet_page(tab_name): with st.expander('''**What are the accessibility measurements and what aspects were considered when the study was designed and implemented?**''', expanded=False): st.write('''The protocol asks about disabilities. Collection accessibility was facilitated through the normal means of the collection sites, including reading questions to participants when needed.''') - st.subheader("**Uses**") + st.header("**Uses**") with st.expander('''**Has the dataset been used for any tasks already? If so, please provide a description.**''', expanded=False): st.write('''A restricted version of the dataset containing raw audio has been used in the Bridge2AI Summer School and hackathon.''') @@ -236,7 +236,7 @@ def healthsheet_page(tab_name): with st.expander('''**Are there tasks for which the dataset should not be used? If so, please provide a description.**''', expanded=False): st.write('''Yes, there are certain applications that are discouraged from using this dataset. Specifically, the dataset should not be used for non-clinical applications such as hiring decisions, insurance premium adjustments, or any form of surveillance that could lead to discrimination or harm. These discouraged uses are intended to prevent unethical or biased outcomes that could negatively impact individuals based on their health conditions or voice characteristics. The dataset is intended strictly for research that prioritize patient safety, privacy, and ethical use.''') - st.subheader("**Dataset Distribution**") + st.header("**Dataset Distribution**") with st.expander('''**Will the dataset be distributed to third parties outside of the entity (e.g., company, institution, organization) on behalf of which the dataset was created?**''', expanded=False): st.write('''The dataset will be distributed broadly to individuals outside of the entity who created the dataset.''') @@ -262,7 +262,7 @@ def healthsheet_page(tab_name): with st.expander('''**Do any export controls or other regulatory restrictions apply to the dataset or to individual instances? If so, please describe these restrictions, and provide a link or other access point to, or otherwise reproduce, any supporting documentation.**''', expanded=False): st.write('''No export controls apply to the dataset.''') - st.subheader("**Maintenance**") + st.header("**Maintenance**") with st.expander('''**Who is supporting/hosting/maintaining the dataset?**''', expanded=False): st.write('''The dataset is supported by the NIH via the Bridge2AI project.
    From 41ced6f38d8f017fa2ebe24913b55cc557211fcc Mon Sep 17 00:00:00 2001 From: Jeff Tang <47529643+jmtang2018@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:34:57 -0500 Subject: [PATCH 17/18] initial --- src/tabs/collection_methods.py | 2 +- src/tabs/study_metadata.py | 129 ++++++++++++++++++++++++++++++++- src/tabs/utils.py | 24 +++++- 3 files changed, 149 insertions(+), 6 deletions(-) diff --git a/src/tabs/collection_methods.py b/src/tabs/collection_methods.py index c806377..f7d5453 100644 --- a/src/tabs/collection_methods.py +++ b/src/tabs/collection_methods.py @@ -41,7 +41,7 @@ def collection_methods_page(tab_name): csv_file_path = "tables/Disease_cohort_inclusion_exclusion_criteria.csv" caption = 'Table 1 - Disease cohort inclusion/exclusion criteria and validation methods' - create_html_table(csv_file_path, caption) + create_html_table(csv_file_path, caption, [], 0) csv_file_path = "tables/Acoustic_Tasks_Protocol.csv" caption = 'Table 2 - Acoustic Tasks in Protocol' diff --git a/src/tabs/study_metadata.py b/src/tabs/study_metadata.py index e5dab46..88be38e 100644 --- a/src/tabs/study_metadata.py +++ b/src/tabs/study_metadata.py @@ -1,6 +1,133 @@ import streamlit as st from tabs.utils import coming_soon_message +from tabs.utils import create_html_table # Define the content of the Study Metadata page def study_metadata_page(tab_name): - coming_soon_message(tab_name) \ No newline at end of file + st.markdown( + """ + Official Title: Bridge2AI-Voice + +Design: Study Type - Observational + +Enrollment Count (Anticipated by 2027): 10,000 + +Design Observation Model +• Cohort + +Design Time Perspective +• Cross-sectional + +Biospecimens: Respiratory, Voice and speech samples + +Biospecimens Description +The Bridge2AI-Voice dataset contains samples from conventional acoustic tasks including respiratory sounds, cough sounds, and free speech prompts, capturing voice, speech and language data relating to health. Participants who consent are asked to perform speaking tasks and complete self-reported demographic and medical history questionnaires, as well as disease-specific validated questionnaires. Participants who consent also permit investigators to access medical information through EHR platforms in order to perform gold standard validation of diagnoses and symptoms + +Eligibility + +Sex +All + +Gender Based +No + +Minimum Age +18 years (this will change when pediatric cohort is introduced, and metadata will be updated to reflect new eligibility criteria) + +Maximum Age +120 years + +Healthy Volunteers +Yes + +Inclusion Criteria +See Table 1 + +Exclusion Criteria +Does not read or speak English (Please note, the Spanish protocols and Data collection will be included in future releases) +See Table 1 + +Study Population +The current v.1.0.0 dataset contains only adult populations. As the study progresses, a pediatric cohort will be introduced. Inclusion/exclusion criteria and additional information regarding the dataset and study metadata will be updated at that time. In addition, the current dataset contains fluent English speakers but will expand to include data collection in Spanish. + +Sampling Method +Non-Probability Sample +Identification Information +Organization Study ID +OT2OD032720 + +Organization Study Type +U.S. National Institutes of Health (NIH) Grant/Contract Award Number + +Secondary ID +ID Link +OT2OD032720 + https://reporter.nih.gov/search/4XtcXzBGEkWQlwG5v8odBA/project-details/10858564 + + + +Collaborators +• University of South Florida +• Weill Cornell Medicine +• Oregon Health & Science University +• Massachusetts Institute of Technology +• University of Toronto +• Mount Sinai Hospital +• Hospital for Sick Children +• Simon Fraser University +• The Hastings Center +• Washington University in St. Louis +• University of Florida +• Vanderbilt University Medical Center + + +URL +How to cite +If you use this dataset for any purpose, please cite the resources specified in the Bridge2AI-Voice documentation for version 1.0.0 of the dataset at (URL) + +Bridge2AI-Voice Consortium (2024). Flagship Voice Dataset from the Bridge2AI-Voice Project (1.0.0) [Dataset]. + +Contact +For any questions, suggestions, or feedback related to this dataset, please email info@b2ai-voice.org + +Acknowledgement +Bridge2AI-Voice is supported by NIH grant OT2OD032720 through the NIH Bridge2AI Common Fund program. +""") + + # Initialize session state for table visibility + if 'show_table_1' not in st.session_state: + st.session_state['show_table_1'] = False + if 'show_table_2' not in st.session_state: + st.session_state['show_table_2'] = False + if 'show_table_3' not in st.session_state: + st.session_state['show_table_3'] = False + + # Button to toggle table visibility + if st.button('Table 1'): + st.session_state['show_table_1'] = not st.session_state['show_table_1'] + + # Conditionally display the table + if st.session_state['show_table_1']: + csv_file_path = "tables/Disease_cohort_inclusion_exclusion_criteria.csv" + caption = 'Table 1 - Disease cohort inclusion/exclusion criteria and validation methods' + create_html_table(csv_file_path, caption, [], 0) + + # Button to toggle table visibility + if st.button('Table 2'): + st.session_state['show_table_2'] = not st.session_state['show_table_2'] + + # Conditionally display the table + if st.session_state['show_table_2']: + csv_file_path = "tables/Acoustic_Tasks_Protocol.csv" + caption = 'Table 2 - Acoustic Tasks in Protocol' + create_html_table(csv_file_path, caption) + + # Button to toggle table visibility + if st.button('Table 3'): + st.session_state['show_table_3'] = not st.session_state['show_table_3'] + + # Conditionally display the table + if st.session_state['show_table_3']: + csv_file_path = "tables/Validated_Questionnaires.csv" + caption = 'Table 3 - Validated Questionnaires integrated into App' + create_html_table(csv_file_path, caption, ['X']) \ No newline at end of file diff --git a/src/tabs/utils.py b/src/tabs/utils.py index da3ea6e..ca4dd94 100644 --- a/src/tabs/utils.py +++ b/src/tabs/utils.py @@ -9,22 +9,29 @@ def coming_soon_message(tab_name): image_path = "images/Wave.png" st.image(image_path, caption='', use_container_width=True) -def create_html_table(csv_file_path, caption=None, cell_values=[]): - # Read CSV file +def create_html_table(csv_file_path, caption=None, cell_values=[], column_index=-1): + # Read CSV file df = pd.read_csv(csv_file_path, dtype=str) # Ensure all columns are read as strings # Replace NaN with an empty string; df = df.fillna("") - + + bold_cells = df.iloc[:, column_index].tolist() if column_index >= 0 else [] + # Convert DataFrame to HTML table html_table = df.to_html(index=False, classes='table table-striped') + + if bold_cells and len(bold_cells) > 0: + for bold_cell in bold_cells: + html_table = html_table.replace(f'{bold_cell}', f'{bold_cell}') + if cell_values and len(cell_values) > 0: for cell_value in cell_values: html_table = html_table.replace(f'{cell_value}', f'{cell_value}') if caption is not None: html_table_with_caption = f""" - +
    @@ -51,9 +58,18 @@ def create_html_table(csv_file_path, caption=None, cell_values=[]): padding: 4px !important; text-align: left; } + + .table th { + background-color: #f2f2f2; + } + .table .center-align { text-align: center; /* Center alignment for specific columns */ } + + .table .bold-cell { + font-weight: bold; /* Bold font for first column cells */ + } """, unsafe_allow_html=True From 0f1c3bb5648ca8624dd194b5c20584d9812f65c8 Mon Sep 17 00:00:00 2001 From: Alexandros Sigaras Date: Thu, 21 Nov 2024 14:08:08 -0500 Subject: [PATCH 18/18] B2AI-541 --- src/tabs/study_metadata.py | 232 +++++++++++++++++-------------------- src/tabs/utils.py | 2 +- 2 files changed, 110 insertions(+), 124 deletions(-) diff --git a/src/tabs/study_metadata.py b/src/tabs/study_metadata.py index 88be38e..936ad65 100644 --- a/src/tabs/study_metadata.py +++ b/src/tabs/study_metadata.py @@ -2,132 +2,118 @@ from tabs.utils import coming_soon_message from tabs.utils import create_html_table +def show_table(key, button_text, show_table, csv_file_path, caption): + if st.button(button_text, key): + st.session_state[show_table] = not st.session_state[show_table] + + # Conditionally display the table + if st.session_state[show_table]: + create_html_table(csv_file_path, caption, [], 0) + # Define the content of the Study Metadata page def study_metadata_page(tab_name): - st.markdown( - """ - Official Title: Bridge2AI-Voice - -Design: Study Type - Observational - -Enrollment Count (Anticipated by 2027): 10,000 - -Design Observation Model -• Cohort - -Design Time Perspective -• Cross-sectional - -Biospecimens: Respiratory, Voice and speech samples - -Biospecimens Description -The Bridge2AI-Voice dataset contains samples from conventional acoustic tasks including respiratory sounds, cough sounds, and free speech prompts, capturing voice, speech and language data relating to health. Participants who consent are asked to perform speaking tasks and complete self-reported demographic and medical history questionnaires, as well as disease-specific validated questionnaires. Participants who consent also permit investigators to access medical information through EHR platforms in order to perform gold standard validation of diagnoses and symptoms - -Eligibility - -Sex -All - -Gender Based -No - -Minimum Age -18 years (this will change when pediatric cohort is introduced, and metadata will be updated to reflect new eligibility criteria) - -Maximum Age -120 years - -Healthy Volunteers -Yes - -Inclusion Criteria -See Table 1 - -Exclusion Criteria -Does not read or speak English (Please note, the Spanish protocols and Data collection will be included in future releases) -See Table 1 - -Study Population -The current v.1.0.0 dataset contains only adult populations. As the study progresses, a pediatric cohort will be introduced. Inclusion/exclusion criteria and additional information regarding the dataset and study metadata will be updated at that time. In addition, the current dataset contains fluent English speakers but will expand to include data collection in Spanish. - -Sampling Method -Non-Probability Sample -Identification Information -Organization Study ID -OT2OD032720 - -Organization Study Type -U.S. National Institutes of Health (NIH) Grant/Contract Award Number - -Secondary ID -ID Link -OT2OD032720 - https://reporter.nih.gov/search/4XtcXzBGEkWQlwG5v8odBA/project-details/10858564 - - - -Collaborators -• University of South Florida -• Weill Cornell Medicine -• Oregon Health & Science University -• Massachusetts Institute of Technology -• University of Toronto -• Mount Sinai Hospital -• Hospital for Sick Children -• Simon Fraser University -• The Hastings Center -• Washington University in St. Louis -• University of Florida -• Vanderbilt University Medical Center - - -URL -How to cite -If you use this dataset for any purpose, please cite the resources specified in the Bridge2AI-Voice documentation for version 1.0.0 of the dataset at (URL) - -Bridge2AI-Voice Consortium (2024). Flagship Voice Dataset from the Bridge2AI-Voice Project (1.0.0) [Dataset]. - -Contact -For any questions, suggestions, or feedback related to this dataset, please email info@b2ai-voice.org - -Acknowledgement -Bridge2AI-Voice is supported by NIH grant OT2OD032720 through the NIH Bridge2AI Common Fund program. -""") # Initialize session state for table visibility if 'show_table_1' not in st.session_state: st.session_state['show_table_1'] = False - if 'show_table_2' not in st.session_state: - st.session_state['show_table_2'] = False - if 'show_table_3' not in st.session_state: - st.session_state['show_table_3'] = False - - # Button to toggle table visibility - if st.button('Table 1'): - st.session_state['show_table_1'] = not st.session_state['show_table_1'] - - # Conditionally display the table - if st.session_state['show_table_1']: - csv_file_path = "tables/Disease_cohort_inclusion_exclusion_criteria.csv" - caption = 'Table 1 - Disease cohort inclusion/exclusion criteria and validation methods' - create_html_table(csv_file_path, caption, [], 0) - - # Button to toggle table visibility - if st.button('Table 2'): - st.session_state['show_table_2'] = not st.session_state['show_table_2'] - - # Conditionally display the table - if st.session_state['show_table_2']: - csv_file_path = "tables/Acoustic_Tasks_Protocol.csv" - caption = 'Table 2 - Acoustic Tasks in Protocol' - create_html_table(csv_file_path, caption) - - # Button to toggle table visibility - if st.button('Table 3'): - st.session_state['show_table_3'] = not st.session_state['show_table_3'] - - # Conditionally display the table - if st.session_state['show_table_3']: - csv_file_path = "tables/Validated_Questionnaires.csv" - caption = 'Table 3 - Validated Questionnaires integrated into App' - create_html_table(csv_file_path, caption, ['X']) \ No newline at end of file + + st.markdown( + """ + Official Title: Bridge2AI-Voice + + Design: Study Type - Observational + + Enrollment Count (Anticipated by 2027): 10,000 + + Design Observation Model + - Cohort + + Design Time Perspective + - Cross-sectional + + Biospecimens: Respiratory, Voice and speech samples + + Biospecimens Description
    + The Bridge2AI-Voice dataset contains samples from conventional acoustic tasks including respiratory sounds, cough sounds, and free speech prompts, capturing voice, speech and language data relating to health. Participants who consent are asked to perform speaking tasks and complete self-reported demographic and medical history questionnaires, as well as disease-specific validated questionnaires. Participants who consent also permit investigators to access medical information through EHR platforms in order to perform gold standard validation of diagnoses and symptoms + + Eligibility + + Sex
    + All + + Gender Based
    + No + + Minimum Age
    + 18 years (this will change when pediatric cohort is introduced, and metadata will be updated to reflect new eligibility criteria) + + Maximum Age
    + 120 years + + Healthy Volunteers
    + Yes + + Inclusion Criteria
    """, unsafe_allow_html=True) + + show_table(1, 'See Collection Methods - Table 1', 'show_table_1', "tables/Disease_cohort_inclusion_exclusion_criteria.csv", 'Table 1 - Disease cohort inclusion/exclusion criteria and validation methods') + + st.markdown( + """ + Exclusion Criteria
    + Does not read or speak English (Please note, the Spanish protocols and Data collection will be included in future releases)
    """, unsafe_allow_html=True) + + show_table(2, 'See Collection Methods - Table 1', 'show_table_1', "tables/Disease_cohort_inclusion_exclusion_criteria.csv", 'Table 1 - Disease cohort inclusion/exclusion criteria and validation methods') + + st.markdown( + """ + Study Population
    + The current v.1.0.0 dataset contains only adult populations. As the study progresses, a pediatric cohort will be introduced. Inclusion/exclusion criteria and additional information regarding the dataset and study metadata will be updated at that time. In addition, the current dataset contains fluent English speakers but will expand to include data collection in Spanish. + + Sampling Method
    + Non-Probability Sample
    + Identification Information
    + Organization Study ID
    + OT2OD032720
    + + Organization Study Type
    + U.S. National Institutes of Health (NIH) Grant/Contract Award Number + + Secondary ID
    +
    {caption}
    + + + + + + + + +
    IDLink
    OT2OD032720https://reporter.nih.gov/search/4XtcXzBGEkWQlwG5v8odBA/project-details/10858564
    + + Collaborators + - University of South Florida + - Weill Cornell Medicine + - Oregon Health & Science University + - Massachusetts Institute of Technology + - University of Toronto + - Mount Sinai Hospital + - Hospital for Sick Children + - Simon Fraser University + - The Hastings Center + - Washington University in St. Louis + - University of Florida + - Vanderbilt University Medical Center + + URL + How to cite + If you use this dataset for any purpose, please cite the resources specified in the Bridge2AI-Voice documentation for version 1.0.0 of the dataset at (URL) + + Bridge2AI-Voice Consortium (2024). Flagship Voice Dataset from the Bridge2AI-Voice Project (1.0.0) [Dataset]. + + Contact + For any questions, suggestions, or feedback related to this dataset, please email info@b2ai-voice.org + + Acknowledgement + Bridge2AI-Voice is supported by NIH grant OT2OD032720 through the NIH Bridge2AI Common Fund program. + """, unsafe_allow_html=True) + \ No newline at end of file diff --git a/src/tabs/utils.py b/src/tabs/utils.py index ca4dd94..ac4c115 100644 --- a/src/tabs/utils.py +++ b/src/tabs/utils.py @@ -31,7 +31,7 @@ def create_html_table(csv_file_path, caption=None, cell_values=[], column_index= if caption is not None: html_table_with_caption = f""" - +
    {caption}