Diff of /openomics_web/app.py [000000] .. [548210]

Switch to unified view

a b/openomics_web/app.py
1
import dash
2
import dash_html_components as html
3
from dash.dependencies import Input, Output, State
4
5
from openomics import MultiOmics
6
from openomics_web.layouts import app_layout
7
from openomics_web.layouts.clinical_view import ClinicalDataColumnSelect, ClinicalDataTable
8
from openomics_web.layouts.datatable_view import ExpressionDataTable, DataTableColumnSelect, split_filter_part
9
from openomics_web.server import server
10
from openomics_web.utils.io import get_table_columns, get_expression_data, get_clinical_data
11
12
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
13
14
# running directly with Python
15
app = dash.Dash(__name__,
16
                server=server,
17
                external_stylesheets=external_stylesheets)
18
19
app.layout = app_layout.app_main()
20
21
user_multiomics = MultiOmics(cohort_name="TEST", )
22
23
24
@app.callback([
25
    Output('data-table-column-select', 'children'),
26
    Output('upload-data-table', 'children')
27
], [
28
    Input('upload-data-table', 'contents'),
29
    Input('upload-data-table', 'filename')
30
], [
31
    State('data-table-type', 'value'),
32
])
33
def update_datatable_metadata(
34
    list_of_contents,
35
    list_of_names,
36
    data_type,
37
):
38
    """
39
    Args:
40
        list_of_contents:
41
        list_of_names:
42
        data_type:
43
    """
44
    if list_of_contents is None:
45
        return None, ['Drag and Drop or ', html.A('Select Files')]
46
47
    try:
48
        columns = get_table_columns(list_of_contents, list_of_names)
49
50
    except Exception as e:
51
        print(e)
52
        return None, 'There was an error processing this file.'
53
54
    return DataTableColumnSelect(columns), "Uploaded {}".format(list_of_names)
55
56
57
@app.callback(Output('output-data-upload', 'children'),
58
              [Input('upload-data-table-submit', 'n_clicks')], [
59
                  State('data-table-cohort', 'value'),
60
                  State('data-table-type', 'value'),
61
                  State('upload-data-table', 'contents'),
62
                  State('upload-data-table', 'filename'),
63
                  State('data-table-genes-col-name', 'value'),
64
                  State('data-table-columns-select', 'value'),
65
                  State('data-table-transpose', 'value')
66
])
67
def import_datatable_upload(n_clicks, cohort_name, data_type, list_of_contents,
68
                            list_of_names, genes_col_name, columns_select,
69
                            transposed):
70
    """
71
    Args:
72
        n_clicks:
73
        cohort_name:
74
        data_type:
75
        list_of_contents:
76
        list_of_names:
77
        genes_col_name:
78
        columns_select:
79
        transposed:
80
    """
81
    if list_of_contents is None:
82
        return []
83
    try:
84
85
        omics_data = get_expression_data(list_of_contents, list_of_names,
86
                                         data_type, cohort_name,
87
                                         genes_col_name, columns_select,
88
                                         transposed)
89
        user_multiomics.add_omic(omics_data)
90
    except Exception as e:
91
        print(e)
92
        return html.Div(['There was an error processing this file.'])
93
94
    return ExpressionDataTable(omics_data.expressions.head(20))
95
96
97
@app.callback(Output('expression-datatable', "data"), [
98
    Input('expression-datatable', "page_current"),
99
    Input('expression-datatable', "page_size"),
100
    Input('expression-datatable', "sort_by"),
101
    Input('expression-datatable', "filter_query")
102
])
103
def update_table(page_current, page_size, sort_by, filter):
104
    """
105
    Args:
106
        page_current:
107
        page_size:
108
        sort_by:
109
        filter:
110
    """
111
    filtering_expressions = filter.split(' && ')
112
    print(user_multiomics.get_omics_list())
113
    dff = user_multiomics[user_multiomics.get_omics_list()[0]]
114
    for filter_part in filtering_expressions:
115
        col_name, operator, filter_value = split_filter_part(filter_part)
116
117
        if operator in ('eq', 'ne', 'lt', 'le', 'gt', 'ge'):
118
            # these operators match pandas series operator method names
119
            dff = dff.loc[getattr(dff[col_name], operator)(filter_value)]
120
        elif operator == 'contains':
121
            dff = dff.loc[dff[col_name].str.contains(filter_value)]
122
        elif operator == 'datestartswith':
123
            # this is a simplification of the front-end filtering logic,
124
            # only works with complete fields in standard format
125
            dff = dff.loc[dff[col_name].str.startswith(filter_value)]
126
127
    if sort_by:
128
        dff = dff.sort_values(
129
            [col['column_id'] for col in sort_by],
130
            ascending=[col['direction'] == 'asc' for col in sort_by],
131
            inplace=False)
132
133
    return dff.iloc[page_current * page_size:(page_current + 1) *
134
                    page_size].to_dict('records')
135
136
137
@app.callback(
138
    [
139
        Output('clinical-column-select', 'children'),
140
        Output('upload-clinical', 'children')
141
    ],
142
    [
143
        Input('upload-clinical', 'contents'),
144
        Input('upload-clinical', 'filename')
145
    ],
146
)
147
def update_clinical_upload_metadata(
148
    file_content,
149
    file_name,
150
):
151
    """
152
    Args:
153
        file_content:
154
        file_name:
155
    """
156
    if file_content is None:
157
        return None, ['Drag and Drop or ', html.A('Select Files')]
158
159
    try:
160
        columns = get_table_columns([
161
            file_content,
162
        ], [
163
            file_name,
164
        ])
165
166
    except Exception as e:
167
        print(e)
168
        return None, 'There was an error processing this file.'
169
170
    return ClinicalDataColumnSelect(columns), "Uploaded {}".format(file_name)
171
172
173
@app.callback(Output('output-clinical-upload', 'children'),
174
              [Input('clinical-submit-button', 'n_clicks')], [
175
                  State('clinical-cohort', 'value'),
176
                  State('clinical-data-type', 'value'),
177
                  State('upload-clinical', 'contents'),
178
                  State('upload-clinical', 'filename'),
179
                  State('clinical-patient-col-name', 'value'),
180
                  State('clinical-data-columns-select', 'value'),
181
])
182
def import_datatable_upload(n_clicks, cohort_name, data_type, list_of_contents,
183
                            list_of_names, patient_id_col, columns_select):
184
    """
185
    Args:
186
        n_clicks:
187
        cohort_name:
188
        data_type:
189
        list_of_contents:
190
        list_of_names:
191
        patient_id_col:
192
        columns_select:
193
    """
194
    if list_of_contents is None:
195
        return []
196
    try:
197
        clinical_data = get_clinical_data(list_of_contents, list_of_names,
198
                                          data_type, cohort_name,
199
                                          patient_id_col, columns_select)
200
        user_multiomics.add_clinical_data(clinical_data)
201
    except Exception as e:
202
        print(e)
203
        return html.Div(['There was an error processing this file.'])
204
205
    return ClinicalDataTable(clinical_data.patient.head(20))
206
207
208
if __name__ == '__main__':
209
    app.run_server(debug=False, port=8050)