def update_run_table(run_name, pathname): if run_name == "Loading...": return None if pathname is None: pathname = "/" path = pathname.split("/") if run_name == "Not found": run = "Run not found!" elif run_name == None or run_name == "": run = "No run selected" else: run = run_name year = run[:2] run_path = keys.run_path + "20{}/{}".format(year, run_name) run_link = "file:/" + run_path if hasattr(keys, "path_platform_windows") and keys.path_platform_windows: run_path = run_path.replace("/", "\\") run_a = html.A(run_path, href=run_link) run_checker_url = "{}/{}".format(keys.run_checker_url, run_name) run_checker_link = html.A(run_checker_url, href=run_checker_url) if len(path) > 2 and path[2] != "": group = path[2] return html_table([["Run Name", run], ["Run Path", run_a], ["Supplying lab", group], ["Run Checker", run_checker_link]]) else: return html_table([["Run Name", run], ["Run Path", run_a], ["Run Checker", run_checker_link]]) return html_table([["Run Name", run]])
def html_test_tables(sample_data, **kwargs): stamps_to_check = ["ssi_stamper", "supplying_lab_check"] rows = [] for key, value in sample_data.items(): if key.startswith("ssi_stamper.whats_my_species") \ or key.startswith("ssi_stamper.assemblatron"): if pd.isnull(value): value = "nan" name_v = key.split(":") values = value.split(':') if len(values) == 3: if values[0] != "pass": rows.append([name_v[1].capitalize(), values[1]]) if (key.endswith(".action")): rows.append(["QC Action", value]) stamp_rows = [] for stamp in stamps_to_check: stamp_key = "stamp.{}.value".format(stamp) if stamp_key in sample_data and not pd.isnull(sample_data[stamp_key]): if str(sample_data[stamp_key]).startswith("pass"): stamp_class = "test-pass" elif str(sample_data[stamp_key]).startswith("fail"): stamp_class = "test-fail" else: stamp_class = "" stamp_rows.append({ "list": [stamp, sample_data[stamp_key]], "className": stamp_class }) if len(rows): test_table = html_table(rows) else: test_table = html.P("No failed tests.") if len(stamp_rows): stamp_table = html_table(stamp_rows) else: stamp_table = html.P("No stamps.") return html.Div([ html.Div([html.H6("QC stamps", className="table-header"), stamp_table], className="six columns"), html.Div( [html.H6("Failed QC tests", className="table-header"), test_table], className="six columns"), ], **kwargs)
def update_run_table(run_name, pathname): if run_name == "Loading...": return None if pathname is None: pathname = "/" path = pathname.split("/") if run_name == "Not found": run = "Run not found!" elif run_name == None or run_name == "": run = "No run selected" else: run = run_name if len(path) > 2 and path[2] != "": group = path[2] return html_table([["Run Name", run], ["Supplying lab", group]]) else: return html_table([["Run Name", run]])
def html_test_table(sample_data,**kwargs): rows = [] for key, value in sample_data.items(): if key.startswith("ssi_stamper.whats_my_species") \ or key.startswith("ssi_stamper.assemblatron"): if pd.isnull(value): value = "nan" name_v = key.split(":") values = value.split(':') if len(values) == 3: if values[0] != "pass": rows.append([name_v[1].capitalize(), values[1]]) if (key.endswith(".action")): rows.append(["QC Action", value]) if len(rows): return html.Div(html_table(rows, className="twelve columns"), **kwargs) else: return html.Div(html.P("No failed tests."), **kwargs)
html.Summary("Latest changes..."), html.Div([ html.P("2019-03-19: Add Priority to run checker."), html.P("2019-03-14: Add Supplying lab feedback option."), html.P("2019-03-07: Add QC values to Run checker."), html. P("2019-02-28: Add assemblatron links to sample folder generator. Only samples run from now on will have the right paths." ), html. P("2019-02-13: Filters default to empty (but behavior is the same), bring back apply button to reduce performance issues, add current run to run selector and other performance fixes. Add Latest changes section." ), ]) ]), dcc.Store(id="data-store", storage_type="memory"), dcc.Location(id="url", refresh=False), html.Div(html_table([["run_name", ""]]), id="run-table"), html_div_summary(), html.Div(id="current-report"), html.Div([ html.H5(["Generate sample folder script"], className="box-title"), html.Div([ html.Div([ html.Button("Assembly/Sample folder", id="generate-folder", n_clicks_timestamp=0, className="button-primary u-full-width") ], className="twelve columns"), ], className="row"),
def html_sample_tables(sample_data, **kwargs): """Generate the tables for each sample containing submitter information, detected organisms etc. """ if "sample_sheet.sample_name" in sample_data: if "sample_sheet.emails" in sample_data and type( sample_data["sample_sheet.emails"]) is str: n_emails = len(sample_data["sample_sheet.emails"].split(";")) if (n_emails > 1): emails = ", ".join( sample_data["sample_sheet.emails"].split(";")[:2]) if (n_emails > 2): emails += ", ..." else: emails = sample_data["sample_sheet.emails"] else: emails = "" sample_sheet_table = html_table([ ["Supplied name", sample_data.get("sample_sheet.sample_name", "")], ["User Comments", sample_data.get("sample_sheet.Comments", "")], ["Supplying lab", sample_data.get("sample_sheet.group", "")], ["Submitter emails", emails], { "list": [ "Provided species", html.I(sample_data.get("sample_sheet.provided_species")) ], "className": check_test("whats_my_species:detectedspeciesmismatch", sample_data) }, { "list": ["Read file", str(sample_data["R1"]).split("/")[-1]], "className": check_test("base:readspresent", sample_data) } ]) else: sample_sheet_table = html_table([]) title = "Assemblatron Results" table = html.Div([ html_table( [{ "list": [ "Number of filtered reads", "{:,.0f}".format( sample_data.get("assemblatron.filtered_reads_num", math.nan)) ], "className": check_test("assemblatron:numreads", sample_data) }, [ "Number of contigs (1x cov.)", "{:,.0f}".format( sample_data.get("assemblatron.bin_contigs_at_1x", math.nan)) ], [ "Number of contigs (10x cov.)", "{:,.0f}".format( sample_data.get("assemblatron.bin_contigs_at_10x", math.nan)) ], [ "N50", "{:,}".format(sample_data.get("assemblatron.N50", math.nan)) ], { "list": [ "Average coverage (1x)", "{:,.2f}".format( sample_data.get("assemblatron.bin_coverage_at_1x", math.nan)) ], "className": check_test("assemblatron:avgcoverage", sample_data) }, { "list": [ "Genome size at 1x depth", "{:,.0f}".format( sample_data.get("assemblatron.bin_length_at_1x", math.nan)) ], "className": check_test("assemblatron:1xgenomesize", sample_data) }, { "list": [ "Genome size at 10x depth", "{:,.0f}".format( sample_data.get("assemblatron.bin_length_at_10x", math.nan)) ], "className": check_test("assemblatron:10xgenomesize", sample_data) }, { "list": [ "Genome size 1x - 10x diff", "{:,.0f}".format( sample_data.get("assemblatron.bin_length_at_1x", math.nan) - sample_data.get("assemblatron.bin_length_at_10x", math.nan)) ], "className": check_test("assemblatron:1x10xsizediff", sample_data) }, [ "Genome size at 25x depth", "{:,.0f}".format( sample_data.get("assemblatron.bin_length_at_25x", math.nan)) ], [ "Ambiguous sites", "{:,.0f}".format( sample_data.get("assemblatron.snp_filter_10x_10%", math.nan)) ]]) ]) resresults = False resfinder = sample_data.get('ariba_resfinder.ariba_resfinder', []) if type(resfinder) == list and len(resfinder): resresults = True resfinder_div = html.Div(dt.DataTable( style_table={ 'overflowX': 'scroll', 'overflowY': 'scroll', 'maxHeight': '480' }, columns=global_vars.finder_columns, data=resfinder, page_action='none'), className="grey-border") elif ( sample_data.get("ariba_resfinder.status", "") == "Success" and (type(resfinder) == float or resfinder is None or not len(resfinder))): resfinder_div = html.P("No antibiotic resistance genes found") else: resfinder_div = html.P("Resfinder not run") plasmidfinder = sample_data.get('ariba_plasmidfinder.ariba_plasmidfinder', []) if type(plasmidfinder) == list and len(plasmidfinder): resresults = True plasmidfinder_div = html.Div(dt.DataTable( style_table={ 'overflowX': 'scroll', 'overflowY': 'scroll', 'maxHeight': '480' }, columns=global_vars.finder_columns, data=plasmidfinder, page_action='none'), className="grey-border") elif (sample_data.get("ariba_plasmidfinder.status", "") == "Success" and (type(plasmidfinder) == float or plasmidfinder is None or not len(plasmidfinder))): plasmidfinder_div = html.P("No replicons found") else: plasmidfinder_div = html.P("Plasmidfinder not run") virulencefinder = sample_data.get( 'ariba_virulencefinder.ariba_virulencefinder', []) if type(virulencefinder) == list and len(virulencefinder): resresults = True virulencefinder_div = html.Div(dt.DataTable( style_table={ 'overflowX': 'scroll', 'overflowY': 'scroll', 'maxHeight': '480' }, columns=global_vars.finder_columns, data=virulencefinder, page_action='none'), className="grey-border") elif sample_data.get("ariba_virulencefinder.status", "") == "Success" and (type(virulencefinder) == float or virulencefinder is None or not len(virulencefinder)): virulencefinder_div = html.P("No virulence markers found") else: virulencefinder_div = html.P("Virulencefinder not run") mlst_data = sample_data.get('ariba_mlst.mlst_report', "") if type(mlst_data) == str and len(mlst_data): resresults = True mlst_dict = {} mlst_fields = mlst_data.split(",") for field in mlst_fields: key, value = field.split(":") mlst_dict[key] = value columns = [{"name": i, "id": i} for i in mlst_dict.keys()] mlst_div = html.Div(dt.DataTable(style_table={ 'overflowX': 'scroll', 'overflowY': 'scroll', 'maxHeight': '480' }, columns=columns, data=[mlst_dict], page_action='none'), className="grey-border") else: mlst_div = html.P("MLST not run") mlst_db = sample_data.get("ariba_mlst.mlst_db", "") # Replace with the ariba_res, ariba_plas and ariba_vir when migrating to them if (sample_data.get("ariba_resfinder.status", "") == "Success" or sample_data.get("ariba_plasmidfinder.status", "") == "Success" or sample_data.get("ariba_mlst.status", "") == "Success" or sample_data.get("ariba_virulencefinder.status", "") == "Success"): res_analysis_not_run = False else: res_analysis_not_run = True if resresults: res_div = html.Details([ html.Summary( "ResFinder/PlasmidFinder/VirulenceFinder/MLST (click to show)" ), html.Div([ html.Div([ html.Div([ html.H6("ResFinder", className="table-header"), resfinder_div ], className="six columns"), html.Div([ html.H6("VirulenceFinder", className="table-header"), virulencefinder_div ], className="six columns") ], className="row"), html.Div([ html.Div([ html.H6("PlasmidFinder", className="table-header"), plasmidfinder_div ], className="six columns"), html.Div([ html.H6("MLST ({})".format(mlst_db), className="table-header"), mlst_div ], className="six columns") ], className="row") ]) ]) elif not resresults and not res_analysis_not_run: res_div = html.Div( html. P("No antibiotic resistances, replicons or virulence markers found for this sample." )) else: res_div = html.Div( html.P( "Resfinder, plasmidfinder and virulencefinder were not run.")) mlst_type = "ND" if "ariba_mlst.mlst_report" in sample_data and sample_data[ "ariba_mlst.mlst_report"] is not None: mlst_report_string = sample_data["ariba_mlst.mlst_report"] if "," in mlst_report_string: mlst_text_split = mlst_report_string.split(",", 1) mlst_type = mlst_text_split[0].split(":", 1)[1] return html.Div([ html.Div([ html.Div([ html.H6("Sample Sheet", className="table-header"), sample_sheet_table, html.H6("Detected Organisms", className="table-header"), html_organisms_table(sample_data) ], className="six columns"), html.Div([ html.H6(title, className="table-header"), table, html.H6("MLST type: {}".format(mlst_type), className="table-header"), ], className="six columns") ], className="row"), html_test_tables(sample_data, className="row"), res_div ], **kwargs)
def html_sample_tables(sample_data, **kwargs): """Generate the tables for each sample containing submitter information, detected organisms etc. """ if "sample_sheet.sample_name" in sample_data: if "sample_sheet.emails" in sample_data and type(sample_data["sample_sheet.emails"]) is str: n_emails = len(sample_data["sample_sheet.emails"].split(";")) if (n_emails > 1): emails = ", ".join( sample_data["sample_sheet.emails"].split(";")[:2]) if (n_emails > 2): emails += ", ..." else: emails = sample_data["sample_sheet.emails"] else: emails = "" sample_sheet_table = html_table([ ["Supplied name", sample_data["sample_sheet.sample_name"]], ["User Comments", sample_data["sample_sheet.Comments"]], ["Supplying lab", sample_data["sample_sheet.group"]], ["Submitter emails", emails], { "list": ["Provided species", html.I( sample_data["sample_sheet.provided_species"])], "className": check_test("whats_my_species:detectedspeciesmismatch", sample_data) }, { "list": ["Read file", str(sample_data["R1"]).split("/")[-1]], "className": check_test("base:readspresent", sample_data) } ]) else: sample_sheet_table = [] title = "Assemblatron Results" table = html.Div([ html_table([ { "list": [ "Number of filtered reads", "{:,.0f}".format( sample_data.get("assemblatron.filtered_reads_num", math.nan)) ], "className": check_test("assemblatron:numreads", sample_data) }, [ "Number of contigs (1x cov.)", "{:,.0f}".format( sample_data.get("assemblatron.bin_contigs_at_1x", math.nan)) ], [ "Number of contigs (10x cov.)", "{:,.0f}".format( sample_data.get("assemblatron.bin_contigs_at_10x", math.nan)) ], [ "N50", "{:,}".format(sample_data.get("assemblatron.N50", math.nan)) ], { "list": [ "Average coverage (1x)", "{:,.2f}".format( sample_data.get("assemblatron.bin_coverage_at_1x", math.nan)) ], "className": check_test("assemblatron:avgcoverage", sample_data) }, { "list": [ "Genome size at 1x depth", "{:,.0f}".format( sample_data.get("assemblatron.bin_length_at_1x", math.nan)) ], "className": check_test("assemblatron:1xgenomesize", sample_data) }, { "list": [ "Genome size at 10x depth", "{:,.0f}".format( sample_data.get("assemblatron.bin_length_at_10x", math.nan)) ], "className": check_test("assemblatron:10xgenomesize", sample_data) }, { "list": [ "Genome size 1x - 10x diff", "{:,.0f}".format( sample_data.get( "assemblatron.bin_length_at_1x", math.nan) - sample_data.get("assemblatron.bin_length_at_10x", math.nan) ) ], "className": check_test("assemblatron:1x10xsizediff", sample_data) }, [ "Genome size at 25x depth", "{:,.0f}".format( sample_data.get("assemblatron.bin_length_at_25x", math.nan)) ], [ "Ambiguous sites", "{:,.0f}".format( sample_data.get("assemblatron.snp_filter_10x_10%", math.nan)) ] ]) ]) resfinder = sample_data.get('analyzer.ariba_resfinder', "[{}]") if type(resfinder) == str: resfinder = resfinder.replace("'", "\"") resfinder = json.loads(resfinder) columns = [] if len(resfinder): columns = [{"name": i, "id": i} for i in resfinder[0].keys()] resfinder_div = html.Div( dt.DataTable( style_table={ 'overflowX': 'scroll', 'overflowY': 'scroll', 'maxHeight': '480' }, columns=columns, data=resfinder, pagination_mode=False ), className="grey-border") if type(resfinder) == float or not len(resfinder): resfinder_div = html.P("No antibiotic resistance genes found") return html.Div([ html.Div([ html.Div([ html.H6("Sample Sheet", className="table-header"), sample_sheet_table, html.H6("Detected Organisms", className="table-header"), html_organisms_table(sample_data) ], className="six columns"), html.Div([ html.H6(title, className="table-header"), table, html.H6("MLST", className="table-header"), html_table([[sample_data.get("analyzer.mlst_report", "No results")]], className="mlst-table") ], className="six columns") ], className="row"), html.Div([ html.Div([ html.H6("Resfinder", className="table-header"), resfinder_div ], className="twelve columns") ], className="row") ], **kwargs)