diff --git a/covigator/__init__.py b/covigator/__init__.py index 9a648a6..c4e7b02 100644 --- a/covigator/__init__.py +++ b/covigator/__init__.py @@ -1,4 +1,4 @@ -VERSION = "v2.2.0" +VERSION = "v2.2.1" ANALYSIS_PIPELINE_VERSION = "v0.15.0" MISSENSE_VARIANT = "missense_variant" diff --git a/covigator/dashboard/dashboard.py b/covigator/dashboard/dashboard.py index b5667f9..f1d9ebb 100644 --- a/covigator/dashboard/dashboard.py +++ b/covigator/dashboard/dashboard.py @@ -65,90 +65,92 @@ def serve_layout(self): footer = get_footer() layout = html.Div(children=[ - dbc.Card([ - dbc.CardHeader( - children=[ - dcc.Location(id='url', refresh=False), - dbc.Navbar( - [ - dbc.Row([ - dbc.Col( - children=html.A(html.Img(src=COVIGATOR_LOGO, - height="80px"), href=HOME_HREF), - className="ml-2", - id="logo" - ), + dbc.Navbar([ + dbc.Row([ + dbc.Col( + children=html.A(html.Img(src=COVIGATOR_LOGO, + height="80px"), href=HOME_HREF), + className="ml-2", + id="logo" + ), + ], + align="left", + className="g-0", + style={'align': 'left'} + ), + dbc.Row( + [ + dbc.Col( + None, + className="ml-2", + id="top-right-logo", + align="left", + style={'margin-left': '2%', } + ), + dbc.Col(html.Br()), + dbc.Col( + dbc.DropdownMenu( + label="Menu", children=[ + dbc.DropdownMenuItem( + "Home", href=HOME_HREF, class_name="m-1", + style={'font-size': '150%', "color": "#003c78"}), + dbc.DropdownMenuItem( + "ENA dashboard", href=ENA_HREF, + style={'font-size': '150%', "color": "#003c78"}), + dbc.DropdownMenuItem( + "COVID-19 Data Portal sequences dashboard", href=COVID_PORTAL_HREF, + style={'font-size': '150%', "color": "#003c78"}), + dbc.DropdownMenuItem( + "Documentation", href="https://covigator.readthedocs.io/en/latest", + target="_blank", + style={'font-size': '150%', "color": "#003c78"}), + dbc.DropdownMenuItem( + "Data download", href=DOWNLOAD_HREF, + style={'font-size': '150%', "color": "#003c78"}), + dbc.DropdownMenuItem( + "Acknowledgements", href=ACKNOWLEDGEMENTS_HREF, + style={'font-size': '150%', "color": "#003c78"}), + dbc.DropdownMenuItem( + "Feedback", href=FEEDBACK_HREF, target="_blank", + style={'font-size': '150%', "color": "#003c78"}), ], - align="left", - className="g-0", - style={'align': 'left'} - ), - dbc.Row( - [ - dbc.Tabs( - None, - id="tabs", - active_tab=SAMPLES_TAB_ID, - style={'align': 'right', 'font-size': '140%'}, - )], - align="right", - style={'margin-left': '2%', } + align_end=True, + size="lg", + toggle_style={ + "textTransform": "uppercase", + "background": "#003c78", + 'font-size': '85%' + }, + style={"margin-left": "15px"} ), - dbc.Row([ - dbc.Col( - None, - className="ml-2", - id="top-right-logo", - align="left", - style={'margin-left': '2%', } - ), - dbc.Col(html.Br()), - dbc.Col( - dbc.DropdownMenu( - label="Menu", children=[ - dbc.DropdownMenuItem( - "Home", href=HOME_HREF, class_name="m-1", - style={'font-size' : '150%', "color": "#003c78"}), - dbc.DropdownMenuItem( - "ENA dashboard", href=ENA_HREF, - style={'font-size' : '150%', "color": "#003c78"}), - dbc.DropdownMenuItem( - "COVID-19 Data Portal sequences dashboard", href=COVID_PORTAL_HREF, - style={'font-size': '150%', "color": "#003c78"}), - dbc.DropdownMenuItem( - "Documentation", href="https://covigator.readthedocs.io/en/latest", - target="_blank", - style={'font-size': '150%', "color": "#003c78"}), - dbc.DropdownMenuItem( - "Data download", href=DOWNLOAD_HREF, - style={'font-size': '150%', "color": "#003c78"}), - dbc.DropdownMenuItem( - "Acknowledgements", href=ACKNOWLEDGEMENTS_HREF, - style={'font-size': '150%', "color": "#003c78"}), - dbc.DropdownMenuItem( - "Feedback", href=FEEDBACK_HREF, target="_blank", - style={'font-size': '150%', "color": "#003c78"}), - ], - align_end=True, - size="lg", - toggle_style={ - "textTransform": "uppercase", - "background": "#003c78", - 'font-size': '85%' - }, - style={"margin-left": "15px"} - ), - style={} - )], - align="right", - justify="end", - style={'float': 'right', 'position': 'absolute', 'right': 0, 'text-align': 'right', - }, - className="g-0 ms-auto flex-nowrap mt-3 mt-md-0", - ) - ] - )], - ), + )], + align="right", + justify="end", + style={'float': 'right', 'position': 'absolute', 'right': 0, 'text-align': 'right', + "margin-right": "1%"}, + className="g-0 ms-auto flex-nowrap mt-3 mt-md-0", + )] + ), + # Wrap tabs into container. The reason to put them not into the + # Card header is because pages without tabs would show the empty + # card header adding additional unused vertical space. + dbc.Container(children=[ + dcc.Location(id='url', refresh=False), + dbc.Row( + dbc.Col( + dbc.Tabs( + None, + id="tabs", + active_tab=SAMPLES_TAB_ID, + style={'align': 'center', 'font-size': '140%',}, + ), + width="auto"), + align="right", justify="left" + + )], + style={'background-color':'#f8f9fa'}, fluid=True + ), + dbc.Card([ dbc.CardBody(dcc.Loading(id="loading-1", children=[html.Div(id=ID_TAB_CONTENT)], style={"height": "100%"})), dbc.CardFooter(footer) ]) diff --git a/covigator/dashboard/tabs/__init__.py b/covigator/dashboard/tabs/__init__.py index 4415805..3f7c575 100644 --- a/covigator/dashboard/tabs/__init__.py +++ b/covigator/dashboard/tabs/__init__.py @@ -4,6 +4,7 @@ MONTH_PATTERN = "%Y-%m" MISSING_VALUE = "-" +APPLY_STYLE = {"height": "38px", "padding": "0 30px"} def print_date(date: datetime.date): return str(date) if date is not None else MISSING_VALUE diff --git a/covigator/dashboard/tabs/intrahost_mutations.py b/covigator/dashboard/tabs/intrahost_mutations.py index c8d4097..5a93376 100644 --- a/covigator/dashboard/tabs/intrahost_mutations.py +++ b/covigator/dashboard/tabs/intrahost_mutations.py @@ -11,6 +11,7 @@ from covigator.dashboard.figures.intrahost_mutations import IntrahostMutationsFigures from covigator.database.queries import Queries +from covigator.dashboard.tabs import APPLY_STYLE TOP_COOCCURRING_CLONAL_VARIANTS = 'top-cooccurring-clonal-variants-table' @@ -172,7 +173,7 @@ def get_subclonal_variants_tab_left_bar(queries: Queries): multi=False ), html.Br(), - html.Button('Apply', id=ID_APPLY_BUTTOM), + dbc.Button('Apply', id=ID_APPLY_BUTTOM, outline=False, color="success", style=APPLY_STYLE), ], className="two columns") diff --git a/covigator/dashboard/tabs/lineages.py b/covigator/dashboard/tabs/lineages.py index 367b21b..528cba2 100644 --- a/covigator/dashboard/tabs/lineages.py +++ b/covigator/dashboard/tabs/lineages.py @@ -8,6 +8,7 @@ from covigator.dashboard.tabs import get_mini_container, print_number, MONTH_PATTERN from covigator.database.model import DataSource from covigator.database.queries import Queries +from covigator.dashboard.tabs import APPLY_STYLE ID_APPLY_BUTTOM = 'lineages-apply-buttom' @@ -152,7 +153,7 @@ def get_lineages_tab_left_bar(queries: Queries, data_source: DataSource): ), html.Br(), html.P("Select a single lineage to explore its corresponding mutations."), - html.Button('Apply', id=ID_APPLY_BUTTOM), + dbc.Button('Apply', id=ID_APPLY_BUTTOM, outline=True, color="success", style=APPLY_STYLE), ]) diff --git a/covigator/dashboard/tabs/mutation_stats.py b/covigator/dashboard/tabs/mutation_stats.py index 7c738b9..e1d5a6f 100644 --- a/covigator/dashboard/tabs/mutation_stats.py +++ b/covigator/dashboard/tabs/mutation_stats.py @@ -6,6 +6,7 @@ from covigator.dashboard.figures.mutation_stats import MutationStatsFigures from covigator.database.model import DataSource, VariantType from covigator.database.queries import Queries +from covigator.dashboard.tabs import APPLY_STYLE ID_VARIANTS_PER_SAMPLE_GRAPH = 'ms-variants-per-sample-graph' @@ -110,7 +111,7 @@ def get_samples_tab_left_bar(queries: Queries, data_source: DataSource): multi=True ), html.Br(), - html.Button('Apply', id=ID_APPLY_BUTTOM), + dbc.Button('Apply', id=ID_APPLY_BUTTOM, outline=False, color="success", style=APPLY_STYLE), ]) diff --git a/covigator/dashboard/tabs/overview.py b/covigator/dashboard/tabs/overview.py index 317d770..fe1fcdb 100644 --- a/covigator/dashboard/tabs/overview.py +++ b/covigator/dashboard/tabs/overview.py @@ -14,37 +14,39 @@ def get_tab_overview(): html.Br(), html.P( """ - Human infections with SARS-CoV-2 are spreading globally since the beginning of 2020, necessitating preventive or - therapeutic strategies and first steps towards an end to this pandemic were done with the approval of the first mRNA - vaccines against SARS-CoV-2. - The accumulation of virus samples that have been sequenced in a short time frame is unprecedented. - This is the first pandemic recorded at a molecular level with such level of detail giving us the opportunity to develop - new tools for the monitoring of its evolution. + CoVigator is a knowledge base and dashboard for SARS-CoV-2 mutations, built by integrating + a full variant calling pipeline. CoVigator dashboard provides readily available interpretation + of mutations along with respective lineages in an interactive visualization. """), html.P( """ - We want to provide an up-to-date interactive view on SARS-CoV-2 mutations to support global efforts in preventing or - treating infections. - Monitoring the appearance of relevant new mutations is key to enable a fast reaction to new strains and for that - purpose we enable the exploration of these mutations and their annotations. - Thus, we envision to help guiding global vaccine design efforts to overcome the threats of this pandemic. - """), - html.P( - """ - CoVigator is a monitoring system for SARS-CoV-2 which integrates a full variant calling pipeline, - a database that stores all relevant information about mutations in SARS-CoV-2 and finally a dashboard to enable - visual analytics. + The main goal for CoVigator is to provide a comprehensive resource with an up-to-date list + of mutations supporting the global efforts of finding emerging SARS-CoV-2 variants. CoVigator + dashboard displays pre-calculated ranked recurrent and intrahost mutations through time, + which facilitates the monitoring of SARS-CoV-2 mutations. + CoVigator process publicly available SARS-CoV-2 raw reads (i.e. FASTQs) from the + European Nucleotide Archive (ENA) and genome assemblies from the COVID-19 Data Portal. + CoVigator is open-data-friendly and allowing it to be adopted to other SARS-CoV-2 data sources. """), html.Br(), html.P(""" - CoVigator loads publicly available SARS-CoV-2 raw reads (ie: FASTQs) from - the European Nucleotide Archive (ENA) and sequences from the COVID-19 Data Portal. - Some samples are present in both datasets. - ENA enables a high resolution analysis into the SARS-CoV-2 mutations through the raw reads. - Intrahost mutations are of particular interest. - On the other hand, the COVID-19 Data Portal sequences have a lower resolution, - but it is a more extensive dataset. + CoVigator provides high-resolution SARS-CoV-2 mutations from genome assemblies and raw + reads allowing confirmation of evolutionary trends. CoVigator pipeline puts a special + emphasis on identification of SARS-CoV-2 intrahost mutations, thus reporting potential + SARS-CoV-2 variants of concern (VoC). CoVigator project is open sourced and made + available under the MIT license. The knowledge base and dashboard source is + hosted at https://github.com/TRON-Bioinformatics/covigator """), + html.Br(), + html.P(""" + If you are interested in our work, please also have a read of our most recent publication. + """), + html.P([ + "Bukur, T., Riesgo-Ferreiro, P., Sorn, P., Gudimella, R., Hausmann, J., Rösler, T., " + "Löwer, M., Schrörs, B., & Sahin, U. CoVigator — A Knowledge Base for Navigating SARS-CoV-2 Genomic Variants. " + "Viruses. 2023; 15(6):1391.", + ], style={"font-style": "italic", "margin-left": "50px"}), + dbc.CardBody( dbc.Row([ @@ -127,7 +129,7 @@ def get_header(): return dbc.Row([ dbc.Col([None], width=2), dbc.Col([html.Div( - [html.Div([html.H1("Monitoring SARS-CoV-2 mutations")], style={"text-align": "left"})], - id="title")], width=5), + [html.Div([html.H1("Welcome to CoVigator Dashboard")], style={"text-align": "left"})], + id="title")], width=4), dbc.Col([None], width=2) ], id="header", className="row flex-display",) \ No newline at end of file diff --git a/covigator/dashboard/tabs/recurrent_mutations.py b/covigator/dashboard/tabs/recurrent_mutations.py index 2809887..f211390 100644 --- a/covigator/dashboard/tabs/recurrent_mutations.py +++ b/covigator/dashboard/tabs/recurrent_mutations.py @@ -10,6 +10,7 @@ from covigator.dashboard.tabs import MONTH_PATTERN from covigator.database.model import DataSource from covigator.database.queries import Queries +from covigator.dashboard.tabs import APPLY_STYLE ID_DROPDOWN_DATE_RANGE_END_DIV = 'dropdown-date-range-end-div' ID_DROPDOWN_GENE = 'dropdown-gene' @@ -209,7 +210,7 @@ def get_variants_tab_left_bar(queries: Queries, data_source: DataSource): tooltip=dict(always_visible=False, placement="right") ), html.Br(), - html.Button('Apply', id=ID_APPLY_BUTTOM), + dbc.Button('Apply', id=ID_APPLY_BUTTOM, outline=False, color="success", style=APPLY_STYLE), ], className="two columns") diff --git a/covigator/dashboard/tabs/samples.py b/covigator/dashboard/tabs/samples.py index 4f5b957..4889c77 100644 --- a/covigator/dashboard/tabs/samples.py +++ b/covigator/dashboard/tabs/samples.py @@ -6,6 +6,7 @@ from covigator.dashboard.figures.samples import SampleFigures from covigator.database.model import DataSource from covigator.database.queries import Queries +from covigator.dashboard.tabs import APPLY_STYLE ID_APPLY_BUTTOM = 's-apply-buttom' @@ -108,7 +109,7 @@ def get_samples_tab_left_bar(queries: Queries, data_source: DataSource): multi=True ), html.Br(), - html.Button('Apply', id=ID_APPLY_BUTTOM), + dbc.Button('Apply', id=ID_APPLY_BUTTOM, outline=False, color="success", style=APPLY_STYLE), ])