Beispiel #1
0
def update_id_output(n_clicks, value):
    if n_clicks > 0:
        if value:
            samples = sf.master_df()
            samples.drop_duplicates(inplace=True)
            parsed_samples = [x.strip() for x in value.split(",")]
            status_df = samples[samples['run_sample_id'].isin(parsed_samples)].iloc[:, [0,1,3,11,10,15,19,17,18]]

            status_df['accession_date'] = status_df['accession_date'] + ', ' + \
                                                 pd.to_datetime(
                                                     status_df['accession_date']).dt.strftime('%a')

            sample_status = dash_table.DataTable(columns=[{"name": i, "id": i} for i in status_df],
                                                 data=status_df.to_dict(
                                                     'records'),
                                                 style_data_conditional=[
                                                     {
                                                         'if': {'row_index': 'odd'},
                                                         'backgroundColor': 'rgb(248,248,248)'
                                                     }
                                                 ],
                                                 style_table={'height': min(40 + 35 * (len(status_df)), 500),
                                                              'overflowY': 'auto'}
                                                 )

            return sample_status
Beispiel #2
0
def per_detect(fc_click, start_date, end_date, value):
    fig = go.Figure()
    if fc_click and value:
        x_lower = (dt.strptime(start_date, '%Y-%m-%d') -
                   timedelta(days=1)).strftime('%m-%d-%Y')
        x_upper = (dt.strptime(end_date, '%Y-%m-%d') +
                   timedelta(days=1)).strftime('%m-%d-%Y')

        samples = sf.master_df()
        g_samples = samples[(samples['date'] >= pd.to_datetime(start_date))
                            & (samples['date'] <= pd.to_datetime(end_date))]

        g_samples.loc[:, 'call_map'] = g_samples.call.map({
            'not_detected': 0,
            'detected': 1
        }) * 100
        percent_detect = g_samples[g_samples['Site Name'].isin(value)].groupby(
            ['Site Name', 'date']).mean().reset_index().rename(
                columns={'call_map': 'Percent Detected'})

        fig = {}
        try:
            title = "Percent Detected By Site From " + start_date[:
                                                                  10] + " To " + end_date[:
                                                                                          10]
            plot_title = {'text': [title], 'fontSize': 16}

            chart = alt.Chart(percent_detect).mark_line().encode(
                x=alt.X('date',
                        title='Date',
                        axis=alt.Axis(titleFontSize=14,
                                      labelFontSize=12,
                                      formatType='time',
                                      format='%a, %b-%d',
                                      labelAngle=45,
                                      grid=False),
                        scale=alt.Scale(domain=[x_lower, x_upper])),
                y=alt.Y(
                    'Percent Detected',
                    title='Percent Detected',
                    scale=alt.Scale(domain=[
                        0, max(percent_detect['Percent Detected']) * 1.05
                    ])),
                tooltip=['date', 'Percent Detected', 'Site Name'],
                color='Site Name')

            fig = chart.properties(
                title=plot_title, width=1200,
                height=250).configure_title(anchor='middle').to_dict()

        except Exception:
            pass

    return fig
Beispiel #3
0
def pie_chart(n_clicks):
    samples = sf.master_df()
    percent = samples[samples['call'] == 'detected'].dropna(
        subset=['Site Name']).replace(
            {'Healing Grove Health Center': 'Healing Grove'})

    low_sites = percent.groupby('Site Name').count()[['runid']].reset_index()
    low_sites['runid'] = (low_sites['runid'] /
                          low_sites.runid.sum()).mul(100).round(2)
    low_sites = low_sites.query("runid < 1")['Site Name'].values.tolist()

    percent.loc[percent['Site Name'].isin(low_sites), 'Site Name'] = "Other"

    percent = percent['Site Name'].value_counts(
        normalize=True).mul(100).round(2)

    data = go.Pie(labels=percent.index.tolist(),
                  values=percent.values.tolist())
    layout = go.Layout(annotations=[
        dict(xref='paper',
             yref='paper',
             x=0.5,
             y=-0.22,
             showarrow=False,
             text=
             f'Other Testing Sites: {*low_sites[0:3],} <br> {*low_sites[3:],}')
    ],
                       title={
                           'text': '% Positive Detection By Site',
                           'y': 0.9,
                           'x': 0.5,
                           'xanchor': 'center',
                           'yanchor': 'top'
                       })
    fig = go.Figure(data=data, layout=layout)
    fig.update_traces(textinfo='percent+label',
                      marker=dict(line=dict(color='#000000', width=2)),
                      textposition='outside')

    return fig
Beispiel #4
0
def update_query_output(n_clicks, start_date, end_date, value):
    if n_clicks > 0:
        samples = sf.master_df()
        samples.drop_duplicates(inplace=True)
        samples = samples[samples['Specimen receipt date'] != 0]

        if value and not start_date and not end_date:
            status_df = samples[samples['Site Name'].isin(value)].sort_values(by='date', ascending=False) \
                            .iloc[:, [0,1,3,11,10,15,19,17,18]]
        elif start_date and end_date and not value:
            status_df = samples[(samples['date'] >= pd.to_datetime(start_date)) & (
                    samples['date'] <= pd.to_datetime(end_date))] \
                            .iloc[:, [0,1,3,11,10,15,19,17,18]]

        elif start_date and end_date and value:
            status_df = samples[(samples['date'] >= pd.to_datetime(start_date)) & (
                    samples['date'] <= pd.to_datetime(end_date))]
            status_df = status_df[status_df['Site Name'].isin(value)].sort_values(by='date', ascending=False) \
                            .iloc[:, [0,1,3,11,10,15,19,17,18]]
        else:
            return

        status_df['accession_date'] = status_df['accession_date'] + ', ' + \
                                             pd.to_datetime(
                                                 status_df['accession_date']).dt.strftime('%a')

        sample_status = dash_table.DataTable(columns=[{"name": i, "id": i} for i in status_df],
                                             data=status_df.to_dict('records'),
                                             style_data_conditional=[
                                                 {
                                                     'if': {'row_index': 'odd'},
                                                     'backgroundColor': 'rgb(248,248,248)'
                                                 }
                                             ],
                                             style_table={'height': 500,
                                                          'overflowY': 'auto'},
                                             sort_action='native'
                                             )

        return sample_status
Beispiel #5
0
def sample_status(fc_click, start_date, end_date):
    fig = {}
    sample_status = []
    if fc_click:
        x_lower = (dt.strptime(start_date, '%Y-%m-%d') -
                   timedelta(days=1)).strftime('%m-%d-%Y')
        x_upper = (dt.strptime(end_date, '%Y-%m-%d') +
                   timedelta(days=1)).strftime('%m-%d-%Y')

        samples = sf.master_df()
        g_samples = samples[(samples['date'] >= pd.to_datetime(start_date))
                            & (samples['date'] <= pd.to_datetime(end_date))]

        dummies = pd.get_dummies(g_samples.flags)
        result = pd.concat([g_samples, dummies], axis=1)
        result = result.groupby('date').mean().reset_index()

        wout_pass = np.delete(g_samples.flags.unique(),
                              np.where(g_samples.flags.unique() == 'pass'))

        for i in wout_pass:
            result[i] = (result[i] * 100).round(2)
            result.rename(columns={i: 'percent-' + i}, inplace=True)

        status = pd.wide_to_long(result,
                                 'percent',
                                 i="date",
                                 j="condition",
                                 sep='-',
                                 suffix=r'.*').reset_index()

        title = "Percent Flag Occurrence From " + start_date[:
                                                             10] + " To " + end_date[:
                                                                                     10]
        plot_title = {'text': [title], 'fontSize': 16}

        chart = alt.Chart(status).mark_line().encode(
            x=alt.X('date',
                    title='Date',
                    axis=alt.Axis(titleFontSize=14,
                                  labelFontSize=12,
                                  formatType='time',
                                  format='%a, %b-%d',
                                  labelAngle=45,
                                  grid=False),
                    scale=alt.Scale(domain=[x_lower, x_upper])),
            y=alt.Y('percent',
                    title='Percent Occurrence',
                    scale=alt.Scale(domain=[0, max(status.percent) * 1.05])),
            tooltip=['date', 'percent', 'condition'],
            color='condition')

        annotation = alt.Chart(status).mark_text(
            align='center', fontSize=15,
            dy=-10).encode(x='date', y='percent',
                           text='percent').transform_filter(
                               (datum.percent > 0))

        fig = (chart + annotation).properties(
            title=plot_title, width=1200,
            height=250).configure_title(anchor='middle').to_dict()

        status_df = g_samples[g_samples['flags'] != 'pass'] \
                        .sort_values(by='date', ascending=False).iloc[:, [0, 1, 3, 11, 15, 19, 17, 18]]
        status_df['accession_date'] = status_df['accession_date'] + ', ' + \
                                      pd.to_datetime(
                                          status_df['accession_date']).dt.strftime('%a')

        sample_status = dash_table.DataTable(columns=[{
            "name": i,
            "id": i
        } for i in status_df],
                                             data=status_df.to_dict('records'),
                                             style_data_conditional=[{
                                                 'if': {
                                                     'row_index': 'odd'
                                                 },
                                                 'backgroundColor':
                                                 'rgb(248,248,248)'
                                             }],
                                             style_table={
                                                 'height': '450px',
                                                 'overflowY': 'auto'
                                             },
                                             sort_action='native')
    return fig, sample_status
Beispiel #6
0
def samples_plot(n_clicks, start_date, end_date):
    fig_total = {}
    fig_tat = {}
    if n_clicks:
        x_lower = (dt.strptime(start_date, '%Y-%m-%d') -
                   timedelta(days=1)).strftime('%m-%d-%Y')
        x_upper = (dt.strptime(end_date, '%Y-%m-%d') +
                   timedelta(days=1)).strftime('%m-%d-%Y')

        samples = sf.master_df()
        samples = samples[(samples['date'] >= pd.to_datetime(start_date))
                          & (samples['date'] <= pd.to_datetime(end_date))]

        #### Total Sample Plot ####
        total_samples = samples.copy()
        total_samples.loc[:, 'sample_type'].replace({'Sample': 1},
                                                    inplace=True)
        total = total_samples.groupby(
            'date').sum().loc[:, ['sample_type']].reset_index()

        # make fig
        title = "Total Clinical Samples per Day, " + start_date[:10] + " to " + end_date[:10] + ": " + str(
            total['sample_type'].sum()) + " Samples"
        plot_title = {'text': [title], 'fontSize': 16}

        bars = alt.Chart(total).mark_bar(size=15).encode(
            x=alt.X('date:T',
                    title='Date',
                    axis=alt.Axis(titleFontSize=14,
                                  labelFontSize=12,
                                  formatType='time',
                                  format='%a, %b-%d',
                                  labelAngle=45,
                                  grid=False),
                    scale=alt.Scale(domain=[x_lower, x_upper])),
            y=alt.Y(
                'sample_type:Q',
                axis=alt.Axis(labelFontSize=12,
                              titleFontSize=14,
                              title='Number of Samples',
                              domain=False),
                scale=alt.Scale(domain=[0, max(total['sample_type']) * 1.1])),
            tooltip=['date', 'sample_type'])

        bar_text = bars.mark_text(
            baseline='top',
            align='center',
            dy=-15,
            color='black',
            fontSize=13,
        ).encode(text=alt.Text('sample_type:Q'))

        fig_total = (bars + bar_text).properties(
            title=plot_title, width=1200, height=250).configure_title(
                anchor='middle').interactive().to_dict()

        #### Turnaround Time Plot ####
        tat_samples = samples.copy()
        tat_samples.dropna(subset=['AIMS Reporting Notified Date'],
                           inplace=True)

        time_diff = pd.to_datetime(tat_samples['AIMS Reporting Notified Date']) \
                    - pd.to_datetime(tat_samples['accession_date'])

        tat_samples['Turnaround Time in Hours'] = (
            time_diff.dt.total_seconds() / 3600)

        tat_samples = tat_samples.groupby('date').agg({
            'Turnaround Time in Hours':
            'mean'
        }).astype('int').reset_index()

        # make fig
        title = "Turnaround Time of Samples per Day, " + start_date[:10] + " to " + end_date[
                                                                                    :10] + " Average Turnaround Time: " + \
                str(tat_samples['Turnaround Time in Hours'].mean().astype('int')) + " Hours"
        plot_title = {'text': [title], 'fontSize': 16}

        bars = alt.Chart(tat_samples).mark_bar(size=15).encode(
            x=alt.X('date:T',
                    title='Date',
                    axis=alt.Axis(titleFontSize=14,
                                  labelFontSize=12,
                                  formatType='time',
                                  format='%a, %b-%d',
                                  labelAngle=45,
                                  grid=False),
                    scale=alt.Scale(domain=[x_lower, x_upper])),
            y=alt.Y(
                'Turnaround Time in Hours:Q',
                axis=alt.Axis(labelFontSize=12,
                              titleFontSize=14,
                              title='Number of Samples',
                              domain=False),
                scale=alt.Scale(domain=[
                    0, max(tat_samples['Turnaround Time in Hours']) * 1.1
                ])),
            tooltip=['date', 'Turnaround Time in Hours'])

        bar_text = bars.mark_text(
            baseline='top',
            align='center',
            dy=-15,
            color='black',
            fontSize=13,
        ).encode(text=alt.Text('Turnaround Time in Hours:Q'))

        rule = alt.Chart(tat_samples).mark_rule(
            color='red', opacity=0.5,
            strokeDash=[3, 3]).encode(y='mean(Turnaround Time in Hours):Q')

        fig_tat = (bars + bar_text + rule).properties(
            title=plot_title, width=1200, height=250).configure_title(
                anchor='middle').interactive().to_dict()

    return fig_total, fig_tat
Beispiel #7
0
def get_layout():
    master = sf.master_df()
    positive = master[master['call'] == 'detected']

    time_diff = pd.to_datetime(master['AIMS Reporting Notified Date']) \
                - pd.to_datetime(master['accession_date'])

    tat = (time_diff.dropna().dt.total_seconds() / 3600).mean().astype(int)

    heading = sf.make_row(children=[
        sf.make_col(children=[
            html.H2(f"To this day, we have processed {len(master)} samples."),
            html.Div(
                html.H2(f"Of those samples, {len(positive)} are positive.")),
            html.Div(
                html.
                H2(f"Average Turnaround Time: {tat} Hours from Accessioning to Reporting."
                   ))
        ]),
        sf.make_col(
            dcc.Graph(id='location-pie',
                      style={'height': 500},
                      config={'displayModeBar': False}))
    ])

    date_range = html.Div([
        dcc.DatePickerRange(id='date-picker-range'),
        html.Div(id='output-container-date-picker-range')
    ])

    fc_submit = sf.make_row(children=[
        sf.make_col(html.Button("Submit",
                                id="fc-button-clinical",
                                n_clicks=0,
                                n_clicks_timestamp=0),
                    col_num=1)
    ])

    submit_res = html.Div(id='button-res-clinical')

    site = pd.read_csv(
        '/ghds/groups/labdesk/bshih/c19dash/c19_dashboard/c19_tat.csv').fillna(
            0)
    site = site[site['Site Name'].notnull()]['Site Name'].unique()
    site.sort()

    site_dropdown = html.Div(
        dcc.Dropdown(id='percent-detect-site-dropdown',
                     options=[{
                         "label": i,
                         "value": i
                     } for i in site],
                     placeholder='Collection Site',
                     multi=True))

    tot_smp_plot = html.Div([dav.VegaLite(id='tot-smp-plot')],
                            style={
                                'width': '100%',
                                'height': '400px'
                            })
    tat_plot = html.Div([dav.VegaLite(id='tat-plot')],
                        style={
                            'width': '100%',
                            'height': '400px'
                        })

    percent_detect = html.Div([dav.VegaLite(id='percent-detect-plot')],
                              style={
                                  'width': '100%',
                                  'height': '400px'
                              })
    total_sample = html.Div([dav.VegaLite(id='total-sample-plot')],
                            style={
                                'width': '100%',
                                'height': '400px'
                            })

    smp_status_plot = html.Div([dav.VegaLite(id='smp-status-plot')],
                               style={
                                   'width': '100%',
                                   'height': '400px'
                               })
    smp_status_table = html.Div(id='smp-status-table',
                                style={
                                    'width': '100%',
                                    'overflowX': 'auto'
                                })

    layout = html.Div([
        heading,
        html.H3('Pick a date range '), date_range, fc_submit, submit_res,
        html.H3('Sample Statistics'), tot_smp_plot, tat_plot,
        html.H3('Site Specific Metrics'), site_dropdown, percent_detect,
        total_sample,
        html.H3('Sample Status'), smp_status_plot, smp_status_table
    ],
                      style={'width': '100%'})

    return layout