def sv_variants(institute_id, case_name): """Display a list of structural variants.""" page = int(request.form.get("page", 1)) variant_type = request.args.get("variant_type", "clinical") category = "sv" # Define case and institute objects institute_obj, case_obj = institute_and_case(store, institute_id, case_name) if request.form.get("hpo_clinical_filter"): case_obj["hpo_clinical_filter"] = True if request.form.getlist("dismiss"): # dismiss a list of variants controllers.dismiss_variant_list( store, institute_obj, case_obj, "variant.sv_variant", request.form.getlist("dismiss"), request.form.getlist("dismiss_choices"), ) # update status of case if visited for the first time controllers.activate_case(store, institute_obj, case_obj, current_user) form = controllers.populate_sv_filters_form(store, institute_obj, case_obj, category, request) cytobands = store.cytoband_by_chrom(case_obj.get("genome_build")) variants_query = store.variants(case_obj["_id"], category=category, query=form.data) # Setup variant count session with variant count by category controllers.variant_count_session(store, institute_id, case_obj["_id"], variant_type, category) result_size = store.count_variants(case_obj["_id"], form.data, None, category) session["filtered_variants"] = result_size # if variants should be exported if request.form.get("export"): return controllers.download_variants(store, case_obj, variants_query) data = controllers.sv_variants(store, institute_obj, case_obj, variants_query, result_size, page) return dict( institute=institute_obj, case=case_obj, dismiss_variant_options=DISMISS_VARIANT_OPTIONS, variant_type=variant_type, form=form, cytobands=cytobands, severe_so_terms=SEVERE_SO_TERMS, manual_rank_options=MANUAL_RANK_OPTIONS, page=page, expand_search=str(request.method == "POST"), **data, )
def sv_variants(institute_id, case_name): """Display a list of structural variants.""" page = int(request.args.get('page', 1)) variant_type = request.args.get('variant_type', 'clinical') form = SvFiltersForm(request.args) institute_obj, case_obj = institute_and_case(store, institute_id, case_name) panel_choices = [(panel['panel_name'], panel['display_name']) for panel in case_obj.get('panels', [])] form.gene_panels.choices = panel_choices query = form.data query['variant_type'] = variant_type variants_query = store.variants(case_obj['_id'], category='sv', query=form.data) data = controllers.sv_variants(store, variants_query, page) return dict(institute=institute_obj, case=case_obj, variant_type=variant_type, form=form, severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
def str_variants(institute_id, case_name): """Display a list of STR variants.""" page = int(request.args.get("page", 1)) variant_type = request.args.get("variant_type", "clinical") category = "str" form = StrFiltersForm(request.args) institute_obj, case_obj = institute_and_case(store, institute_id, case_name) controllers.activate_case(store, institute_obj, case_obj, current_user) query = form.data query["variant_type"] = variant_type variants_query = store.variants(case_obj["_id"], category=category, query=query).sort( [ ("str_repid", pymongo.ASCENDING), ("chromosome", pymongo.ASCENDING), ("position", pymongo.ASCENDING), ] ) data = controllers.str_variants(store, institute_obj, case_obj, variants_query, page) return dict( institute=institute_obj, case=case_obj, dismiss_variant_options=DISMISS_VARIANT_OPTIONS, variant_type=variant_type, manual_rank_options=MANUAL_RANK_OPTIONS, form=form, page=page, **data, )
def str_variants(institute_id, case_name): """Display a list of STR variants.""" page = int(request.args.get('page', 1)) variant_type = request.args.get('variant_type', 'clinical') form = StrFiltersForm(request.args) institute_obj, case_obj = institute_and_case(store, institute_id, case_name) query = form.data query['variant_type'] = variant_type variants_query = store.variants(case_obj['_id'], category='str', query=query) data = controllers.str_variants(store, institute_obj, case_obj, variants_query, page) return dict(institute=institute_obj, case=case_obj, variant_type = variant_type, form=form, page=page, **data)
def cancer_sv_variants(institute_id, case_name): """Display a list of cancer structural variants.""" page = int(request.form.get("page", 1)) variant_type = request.args.get("variant_type", "clinical") category = "cancer_sv" # Define case and institute objects institute_obj, case_obj = institute_and_case(store, institute_id, case_name) if request.form.get("hpo_clinical_filter"): case_obj["hpo_clinical_filter"] = True # update status of case if visited for the first time controllers.activate_case(store, institute_obj, case_obj, current_user) form = controllers.populate_sv_filters_form(store, institute_obj, case_obj, category, request) variants_query = store.variants(case_obj["_id"], category=category, query=form.data) # if variants should be exported if request.form.get("export"): return controllers.download_variants(store, case_obj, variants_query) data = controllers.sv_variants(store, institute_obj, case_obj, variants_query, page) return dict(institute=institute_obj, case=case_obj, variant_type=variant_type, form=form, severe_so_terms=SEVERE_SO_TERMS, cancer_tier_options=CANCER_TIER_OPTIONS, manual_rank_options=MANUAL_RANK_OPTIONS, page=page, **data)
def variants(institute_id, case_name): """Display a list of SNV variants.""" page = int(request.args.get('page', 1)) institute_obj, case_obj = institute_and_case(store, institute_id, case_name) form = FiltersForm(request.args) panel_choices = [(panel['panel_name'], panel['display_name']) for panel in case_obj.get('panels', [])] form.gene_panels.choices = panel_choices # update status of case if vistited for the first time if case_obj['status'] == 'inactive' and not current_user.is_admin: flash('You just activated this case!', 'info') user_obj = store.user(current_user.email) case_link = url_for('cases.case', institute_id=institute_obj['_id'], case_name=case_obj['display_name']) store.update_status(institute_obj, case_obj, user_obj, 'active', case_link) # handle HPO gene list separately if form.data['gene_panels'] == ['hpo']: hpo_symbols = list( set(term_obj['hgnc_symbol'] for term_obj in case_obj['dynamic_gene_list'])) form.hgnc_symbols.data = hpo_symbols variants_query = store.variants(case_obj['_id'], query=form.data) data = controllers.variants(store, variants_query, page) return dict(institute=institute_obj, case=case_obj, form=form, severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
def variants(institute_id, case_name): """Display a list of SNV variants.""" page = int(request.form.get('page', 1)) institute_obj, case_obj = institute_and_case(store, institute_id, case_name) variant_type = request.args.get('variant_type', 'clinical') # Update filter settings if Clinical Filter was requested default_panels = [] for panel in case_obj['panels']: if panel.get('is_default'): default_panels.append(panel['panel_name']) request.form.get('gene_panels') if bool(request.form.get('clinical_filter')): clinical_filter = MultiDict({ 'variant_type': 'clinical', 'region_annotations': ['exonic', 'splicing'], 'functional_annotations': SEVERE_SO_TERMS, 'clinsig': [4, 5], 'clinsig_confident_always_returned': True, 'gnomad_frequency': str(institute_obj['frequency_cutoff']), 'variant_type': 'clinical', 'gene_panels': default_panels }) if (request.method == "POST"): if bool(request.form.get('clinical_filter')): form = FiltersForm(clinical_filter) form.csrf_token = request.args.get('csrf_token') else: form = FiltersForm(request.form) else: form = FiltersForm(request.args) # populate available panel choices available_panels = case_obj.get('panels', []) + [{ 'panel_name': 'hpo', 'display_name': 'HPO' }] panel_choices = [(panel['panel_name'], panel['display_name']) for panel in available_panels] form.gene_panels.choices = panel_choices # upload gene panel if symbol file exists if (request.files): file = request.files[form.symbol_file.name] if request.files and file and file.filename != '': log.debug("Upload file request files: {0}".format( request.files.to_dict())) try: stream = io.StringIO(file.stream.read().decode('utf-8'), newline=None) except UnicodeDecodeError as error: flash("Only text files are supported!", 'warning') return redirect(request.referrer) hgnc_symbols_set = set(form.hgnc_symbols.data) log.debug("Symbols prior to upload: {0}".format(hgnc_symbols_set)) new_hgnc_symbols = controllers.upload_panel(store, institute_id, case_name, stream) hgnc_symbols_set.update(new_hgnc_symbols) form.hgnc_symbols.data = hgnc_symbols_set # reset gene panels form.gene_panels.data = '' # update status of case if vistited for the first time if case_obj['status'] == 'inactive' and not current_user.is_admin: flash('You just activated this case!', 'info') user_obj = store.user(current_user.email) case_link = url_for('cases.case', institute_id=institute_obj['_id'], case_name=case_obj['display_name']) store.update_status(institute_obj, case_obj, user_obj, 'active', case_link) # check if supplied gene symbols exist hgnc_symbols = [] non_clinical_symbols = [] not_found_symbols = [] not_found_ids = [] if (form.hgnc_symbols.data) and len(form.hgnc_symbols.data) > 0: is_clinical = form.data.get('variant_type', 'clinical') == 'clinical' clinical_symbols = store.clinical_symbols( case_obj) if is_clinical else None for hgnc_symbol in form.hgnc_symbols.data: if hgnc_symbol.isdigit(): hgnc_gene = store.hgnc_gene(int(hgnc_symbol)) if hgnc_gene is None: not_found_ids.append(hgnc_symbol) else: hgnc_symbols.append(hgnc_gene['hgnc_symbol']) elif store.hgnc_genes(hgnc_symbol).count() == 0: not_found_symbols.append(hgnc_symbol) elif is_clinical and (hgnc_symbol not in clinical_symbols): non_clinical_symbols.append(hgnc_symbol) else: hgnc_symbols.append(hgnc_symbol) if (not_found_ids): flash("HGNC id not found: {}".format(", ".join(not_found_ids)), 'warning') if (not_found_symbols): flash("HGNC symbol not found: {}".format(", ".join(not_found_symbols)), 'warning') if (non_clinical_symbols): flash( "Gene not included in clinical list: {}".format( ", ".join(non_clinical_symbols)), 'warning') form.hgnc_symbols.data = hgnc_symbols # handle HPO gene list separately if form.data['gene_panels'] == ['hpo']: hpo_symbols = list( set(term_obj['hgnc_symbol'] for term_obj in case_obj['dynamic_gene_list'])) form.hgnc_symbols.data = hpo_symbols variants_query = store.variants(case_obj['_id'], query=form.data) data = {} if request.form.get('export'): document_header = controllers.variants_export_header(case_obj) export_lines = [] if form.data['chrom'] == 'MT': # Return all MT variants export_lines = controllers.variant_export_lines( store, case_obj, variants_query) else: # Return max 500 variants export_lines = controllers.variant_export_lines( store, case_obj, variants_query.limit(500)) def generate(header, lines): yield header + '\n' for line in lines: yield line + '\n' headers = Headers() headers.add('Content-Disposition', 'attachment', filename=str(case_obj['display_name']) + '-filtered_variants.csv') # return a csv with the exported variants return Response(generate(",".join(document_header), export_lines), mimetype='text/csv', headers=headers) data = controllers.variants(store, institute_obj, case_obj, variants_query, page) return dict(institute=institute_obj, case=case_obj, form=form, severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
def sv_variants(institute_id, case_name): """Display a list of structural variants.""" page = int(request.form.get('page', 1)) variant_type = request.args.get('variant_type', 'clinical') institute_obj, case_obj = institute_and_case(store, institute_id, case_name) form = SvFiltersForm(request.form) default_panels = [] for panel in case_obj['panels']: if panel['is_default']: default_panels.append(panel['panel_name']) request.form.get('gene_panels') if bool(request.form.get('clinical_filter')): clinical_filter = MultiDict({ 'variant_type': 'clinical', 'region_annotations': ['exonic', 'splicing'], 'functional_annotations': SEVERE_SO_TERMS, 'thousand_genomes_frequency': str(institute_obj['frequency_cutoff']), 'variant_type': 'clinical', 'clingen_ngi': 10, 'swegen': 10, 'size': 100, 'gene_panels': default_panels }) if (request.method == "POST"): if bool(request.form.get('clinical_filter')): form = SvFiltersForm(clinical_filter) form.csrf_token = request.args.get('csrf_token') else: form = SvFiltersForm(request.form) else: form = SvFiltersForm(request.args) available_panels = case_obj.get('panels', []) + [{ 'panel_name': 'hpo', 'display_name': 'HPO' }] panel_choices = [(panel['panel_name'], panel['display_name']) for panel in available_panels] form.gene_panels.choices = panel_choices if form.data['gene_panels'] == ['hpo']: hpo_symbols = list( set(term_obj['hgnc_symbol'] for term_obj in case_obj['dynamic_gene_list'])) form.hgnc_symbols.data = hpo_symbols # update status of case if vistited for the first time if case_obj['status'] == 'inactive' and not current_user.is_admin: flash('You just activated this case!', 'info') user_obj = store.user(current_user.email) case_link = url_for('cases.case', institute_id=institute_obj['_id'], case_name=case_obj['display_name']) store.update_status(institute_obj, case_obj, user_obj, 'active', case_link) variants_query = store.variants(case_obj['_id'], category='sv', query=form.data) data = {} # if variants should be exported if request.form.get('export'): document_header = controllers.variants_export_header(case_obj) export_lines = [] # Return max 500 variants export_lines = controllers.variant_export_lines( store, case_obj, variants_query.limit(500)) def generate(header, lines): yield header + '\n' for line in lines: yield line + '\n' headers = Headers() headers.add('Content-Disposition', 'attachment', filename=str(case_obj['display_name']) + '-filtered_sv-variants.csv') return Response( generate(",".join(document_header), export_lines), mimetype='text/csv', headers=headers) # return a csv with the exported variants else: data = controllers.sv_variants(store, institute_obj, case_obj, variants_query, page) return dict(institute=institute_obj, case=case_obj, variant_type=variant_type, form=form, severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
def variants(institute_id, case_name): """Display a list of SNV variants.""" page = int(request.form.get("page", 1)) category = "snv" institute_obj, case_obj = institute_and_case(store, institute_id, case_name) variant_type = request.args.get("variant_type", "clinical") if request.form.get("hpo_clinical_filter"): case_obj["hpo_clinical_filter"] = True user_obj = store.user(current_user.email) if request.method == "POST": # If special filter buttons were selected: form = controllers.populate_filters_form( store, institute_obj, case_obj, user_obj, category, request.form ) else: form = FiltersForm(request.args) # set form variant data type the first time around form.variant_type.data = variant_type # populate filters dropdown available_filters = store.filters(institute_id, category) form.filters.choices = [ (filter.get("_id"), filter.get("display_name")) for filter in available_filters ] # populate available panel choices available_panels = case_obj.get("panels", []) + [ {"panel_name": "hpo", "display_name": "HPO"} ] panel_choices = [ (panel["panel_name"], panel["display_name"]) for panel in available_panels ] form.gene_panels.choices = panel_choices # update status of case if visited for the first time controllers.activate_case(store, institute_obj, case_obj, current_user) # upload gene panel if symbol file exists if request.files: file = request.files[form.symbol_file.name] if request.files and file and file.filename != "": log.debug("Upload file request files: {0}".format(request.files.to_dict())) try: stream = io.StringIO(file.stream.read().decode("utf-8"), newline=None) except UnicodeDecodeError as error: flash("Only text files are supported!", "warning") return redirect(request.referrer) hgnc_symbols_set = set(form.hgnc_symbols.data) log.debug("Symbols prior to upload: {0}".format(hgnc_symbols_set)) new_hgnc_symbols = controllers.upload_panel( store, institute_id, case_name, stream ) hgnc_symbols_set.update(new_hgnc_symbols) form.hgnc_symbols.data = hgnc_symbols_set # reset gene panels form.gene_panels.data = "" # check if supplied gene symbols exist hgnc_symbols = [] non_clinical_symbols = [] not_found_symbols = [] not_found_ids = [] if (form.hgnc_symbols.data) and len(form.hgnc_symbols.data) > 0: is_clinical = form.data.get("variant_type", "clinical") == "clinical" clinical_symbols = store.clinical_symbols(case_obj) if is_clinical else None for hgnc_symbol in form.hgnc_symbols.data: if hgnc_symbol.isdigit(): hgnc_gene = store.hgnc_gene(int(hgnc_symbol)) if hgnc_gene is None: not_found_ids.append(hgnc_symbol) else: hgnc_symbols.append(hgnc_gene["hgnc_symbol"]) elif sum(1 for i in store.hgnc_genes(hgnc_symbol)) == 0: not_found_symbols.append(hgnc_symbol) elif is_clinical and (hgnc_symbol not in clinical_symbols): non_clinical_symbols.append(hgnc_symbol) else: hgnc_symbols.append(hgnc_symbol) if not_found_ids: flash("HGNC id not found: {}".format(", ".join(not_found_ids)), "warning") if not_found_symbols: flash( "HGNC symbol not found: {}".format(", ".join(not_found_symbols)), "warning" ) if non_clinical_symbols: flash( "Gene not included in clinical list: {}".format( ", ".join(non_clinical_symbols) ), "warning", ) form.hgnc_symbols.data = hgnc_symbols # handle HPO gene list separately if "hpo" in form.data["gene_panels"]: hpo_symbols = list( set(term_obj["hgnc_symbol"] for term_obj in case_obj["dynamic_gene_list"]) ) current_symbols = set(hgnc_symbols) current_symbols.update(hpo_symbols) form.hgnc_symbols.data = list(current_symbols) variants_query = store.variants(case_obj["_id"], query=form.data, category=category) if request.form.get("export"): return controllers.download_variants(store, case_obj, variants_query) data = controllers.variants(store, institute_obj, case_obj, variants_query, page) return dict( institute=institute_obj, case=case_obj, form=form, manual_rank_options=MANUAL_RANK_OPTIONS, cancer_tier_options=CANCER_TIER_OPTIONS, severe_so_terms=SEVERE_SO_TERMS, page=page, **data )
def cancer_variants(institute_id, case_name): """Show cancer variants overview.""" category = "cancer" institute_obj, case_obj = institute_and_case(store, institute_id, case_name) user_obj = store.user(current_user.email) if request.method == "POST": form = controllers.populate_filters_form(store, institute_obj, case_obj, user_obj, category, request.form) # if user is not loading an existing filter, check filter form if request.form.get( "load_filter") is None and form.validate_on_submit() is False: # Flash a message with errors for field, err_list in form.errors.items(): for err in err_list: flash(f"Content of field '{field}' has not a valid format", "warning") # And do not submit the form return redirect( url_for( ".cancer_variants", institute_id=institute_id, case_name=case_name, expand_search="True", ), ) page = int(request.form.get("page", 1)) else: page = int(request.args.get("page", 1)) form = CancerFiltersForm(request.args) form.chrom.data = request.args.get("chrom", None) # update status of case if visited for the first time controllers.activate_case(store, institute_obj, case_obj, current_user) # populate filters dropdown available_filters = store.filters(institute_id, category) form.filters.choices = [(filter.get("_id"), filter.get("display_name")) for filter in available_filters] available_panels = case_obj.get("panels", []) + [{ "panel_name": "hpo", "display_name": "HPO" }] panel_choices = [(panel["panel_name"], panel["display_name"]) for panel in available_panels] form.gene_panels.choices = panel_choices cytobands = store.cytoband_by_chrom(case_obj.get("genome_build")) variant_type = request.args.get("variant_type", "clinical") variants_query = store.variants(case_obj["_id"], category="cancer", query=form.data) if request.form.get("export"): return controllers.download_variants(store, case_obj, variants_query) data = controllers.cancer_variants(store, institute_id, case_name, variants_query, form, page=page) return dict( variant_type=variant_type, cytobands=cytobands, dismiss_variant_options={ **DISMISS_VARIANT_OPTIONS, **CANCER_SPECIFIC_VARIANT_DISMISS_OPTIONS, }, expand_search=str(request.method == "POST"), **data, )
def cancer_variants(institute_id, case_name): """Show cancer variants overview.""" category = "cancer" variant_type = Markup.escape(request.args.get("variant_type", "clinical")) institute_obj, case_obj = institute_and_case(store, institute_id, case_name) variants_stats = store.case_variants_count(case_obj["_id"], institute_id, variant_type, False) user_obj = store.user(current_user.email) if request.method == "POST": if "dismiss_submit" in request.form: # dismiss a list of variants controllers.dismiss_variant_list( store, institute_obj, case_obj, "variant.variant", request.form.getlist("dismiss"), request.form.getlist("dismiss_choices"), ) form = controllers.populate_filters_form( store, institute_obj, case_obj, user_obj, category, request.form ) # if user is not loading an existing filter, check filter form if ( request.form.get("load_filter") is None and request.form.get("audit_filter") is None and form.validate_on_submit() is False ): # Flash a message with errors for field, err_list in form.errors.items(): for err in err_list: flash(f"Content of field '{field}' does not have a valid format", "warning") # And do not submit the form return redirect( url_for( ".cancer_variants", institute_id=institute_id, case_name=case_name, expand_search=True, ) ) page = int(Markup.escape(request.form.get("page", "1"))) else: page = int(Markup.escape(request.args.get("page", "1"))) form = CancerFiltersForm(request.args) # set chromosome to all chromosomes form.chrom.data = request.args.get("chrom", "") if form.gene_panels.data == []: form.gene_panels.data = controllers.case_default_panels(case_obj) # update status of case if visited for the first time controllers.activate_case(store, institute_obj, case_obj, current_user) # populate filters dropdown available_filters = list(store.filters(institute_id, category)) form.filters.choices = [ (filter.get("_id"), filter.get("display_name")) for filter in available_filters ] # Populate chromosome select choices controllers.populate_chrom_choices(form, case_obj) form.gene_panels.choices = controllers.gene_panel_choices(store, institute_obj, case_obj) genome_build = "38" if "38" in str(case_obj.get("genome_build")) else "37" cytobands = store.cytoband_by_chrom(genome_build) controllers.update_form_hgnc_symbols(store, case_obj, form) variants_query = store.variants( case_obj["_id"], category="cancer", query=form.data, build=genome_build ) result_size = store.count_variants(case_obj["_id"], form.data, None, category) if request.form.get("export"): return controllers.download_variants(store, case_obj, variants_query) data = controllers.cancer_variants( store, institute_id, case_name, variants_query, result_size, form, page=page, ) expand_search = request.method == "POST" and request.form.get("expand_search") in [ "True", "", ] return dict( variant_type=variant_type, cytobands=cytobands, filters=available_filters, dismiss_variant_options={ **DISMISS_VARIANT_OPTIONS, **CANCER_SPECIFIC_VARIANT_DISMISS_OPTIONS, }, expand_search=expand_search, result_size=result_size, total_variants=variants_stats.get(variant_type, {}).get(category, "NA"), **data, )
def variants(institute_id, case_name): """Display a list of SNV variants.""" page = int(request.args.get('page', 1)) institute_obj, case_obj = institute_and_case(store, institute_id, case_name) form = FiltersForm(request.args) panel_choices = [(panel['panel_name'], panel['display_name']) for panel in case_obj.get('panels', [])] form.gene_panels.choices = panel_choices # update status of case if vistited for the first time if case_obj['status'] == 'inactive' and not current_user.is_admin: flash('You just activated this case!', 'info') user_obj = store.user(current_user.email) case_link = url_for('cases.case', institute_id=institute_obj['_id'], case_name=case_obj['display_name']) store.update_status(institute_obj, case_obj, user_obj, 'active', case_link) # check if supplied gene symbols exist hgnc_symbols = [] if len(form.hgnc_symbols.data) > 0: is_clinical = form.data.get('variant_type', 'clinical') == 'clinical' clinical_symbols = store.clinical_symbols( case_obj) if is_clinical else None for hgnc_symbol in form.hgnc_symbols.data: if hgnc_symbol.isdigit(): hgnc_gene = store.hgnc_gene(int(hgnc_symbol)) if hgnc_gene is None: flash("HGNC id not found: {}".format(hgnc_symbol), 'warning') else: hgnc_symbols.append(hgnc_gene['hgnc_symbol']) elif store.hgnc_genes(hgnc_symbol).count() == 0: flash("HGNC symbol not found: {}".format(hgnc_symbol), 'warning') elif is_clinical and (hgnc_symbol not in clinical_symbols): flash( "Gene not included in clinical list: {}".format( hgnc_symbol), 'warning') else: hgnc_symbols.append(hgnc_symbol) form.hgnc_symbols.data = hgnc_symbols # handle HPO gene list separately if form.data['gene_panels'] == ['hpo']: hpo_symbols = list( set(term_obj['hgnc_symbol'] for term_obj in case_obj['dynamic_gene_list'])) form.hgnc_symbols.data = hpo_symbols variants_query = store.variants(case_obj['_id'], query=form.data) data = {} if request.args.get('export'): document_header = controllers.variants_export_header(case_obj) export_lines = [] if form.data['chrom'] == 'MT': # Return all MT variants export_lines = controllers.variant_export_lines( store, case_obj, variants_query) else: # Return max 500 variants export_lines = controllers.variant_export_lines( store, case_obj, variants_query.limit(500)) def generate(header, lines): yield header + '\n' for line in lines: yield line + '\n' headers = Headers() headers.add('Content-Disposition', 'attachment', filename=str(case_obj['_id']) + '-filtered_variants.csv') return Response( generate(",".join(document_header), export_lines), mimetype='text/csv', headers=headers) # return a csv with the exported variants else: data = controllers.variants(store, institute_obj, case_obj, variants_query, page) return dict(institute=institute_obj, case=case_obj, form=form, severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
def mt_excel_files(store, case_obj, temp_excel_dir): """Collect MT variants and format line of a MT variant report to be exported in excel format. Create mt excel files, one for each sample, in a temporary directory. Args: store(adapter.MongoAdapter) case_obj(models.Case) temp_excel_dir(os.Path): folder where the temp excel files are written to Returns: written_files(int): the number of files written to temp_excel_dir """ today = datetime.datetime.now().strftime("%Y-%m-%d") samples = case_obj.get("individuals") file_header = MT_EXPORT_HEADER coverage_stats = None # if chanjo connection is established, include MT vs AUTOSOME coverage stats if current_app.config.get("SQLALCHEMY_DATABASE_URI"): coverage_stats = mt_coverage_stats(samples) query = {"chrom": "MT"} mt_variants = list( store.variants(case_id=case_obj["_id"], query=query, nr_of_variants=-1, sort_key="position") ) written_files = 0 for sample in samples: sample_id = sample["individual_id"] display_name = sample["display_name"] sample_lines = export_mt_variants(variants=mt_variants, sample_id=sample_id) # set up document name document_name = ".".join([case_obj["display_name"], display_name, today]) + ".xlsx" workbook = Workbook(os.path.join(temp_excel_dir, document_name)) Report_Sheet = workbook.add_worksheet() # Write the column header row = 0 for col, field in enumerate(MT_EXPORT_HEADER): Report_Sheet.write(row, col, field) # Write variant lines, after header (start at line 1) for row, line in enumerate(sample_lines, 1): # each line becomes a row in the document for col, field in enumerate(line): # each field in line becomes a cell Report_Sheet.write(row, col, field) if bool( coverage_stats ): # it's None if app is not connected to Chanjo or {} if samples are not in Chanjo db # Write coverage stats header after introducing 2 empty lines for col, field in enumerate(MT_COV_STATS_HEADER): Report_Sheet.write(row + 3, col, field) # Write sample MT vs autosome coverage stats to excel sheet for col, item in enumerate(["mt_coverage", "autosome_cov", "mt_copy_number"]): Report_Sheet.write(row + 4, col, coverage_stats[sample_id].get(item)) workbook.close() if os.path.exists(os.path.join(temp_excel_dir, document_name)): written_files += 1 return written_files
def variants(institute_id, case_name): """Display a list of SNV variants.""" page = int(request.args.get('page', 1)) institute_obj, case_obj = institute_and_case(store, institute_id, case_name) form = FiltersForm(request.args) panel_choices = [(panel['panel_name'], panel['display_name']) for panel in case_obj.get('panels', [])] form.gene_panels.choices = panel_choices # update status of case if vistited for the first time if case_obj['status'] == 'inactive' and not current_user.is_admin: flash('You just activated this case!', 'info') user_obj = store.user(current_user.email) case_link = url_for('cases.case', institute_id=institute_obj['_id'], case_name=case_obj['display_name']) store.update_status(institute_obj, case_obj, user_obj, 'active', case_link) # check if supplied gene symbols exist hgnc_symbols = [] if len(form.hgnc_symbols.data) > 0: is_clinical = form.data.get('variant_type', 'clinical') == 'clinical' clinical_symbols = store.clinical_symbols( case_obj) if is_clinical else None for hgnc_symbol in form.hgnc_symbols.data: if hgnc_symbol.isdigit(): hgnc_gene = store.hgnc_gene(int(hgnc_symbol)) if hgnc_gene is None: flash("HGNC id not found: {}".format(hgnc_symbol), 'warning') else: hgnc_symbols.append(hgnc_gene['hgnc_symbol']) elif store.hgnc_genes(hgnc_symbol).count() == 0: flash("HGNC symbol not found: {}".format(hgnc_symbol), 'warning') elif is_clinical and (hgnc_symbol not in clinical_symbols): flash( "Gene not included in clinical list: {}".format( hgnc_symbol), 'warning') else: hgnc_symbols.append(hgnc_symbol) form.hgnc_symbols.data = hgnc_symbols # handle HPO gene list separately if form.data['gene_panels'] == ['hpo']: hpo_symbols = list( set(term_obj['hgnc_symbol'] for term_obj in case_obj['dynamic_gene_list'])) form.hgnc_symbols.data = hpo_symbols variants_query = store.variants(case_obj['_id'], query=form.data) data = controllers.variants(store, institute_obj, case_obj, variants_query, page) return dict(institute=institute_obj, case=case_obj, form=form, severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
def str_variants(institute_id, case_name): """Display a list of STR variants.""" page = int(Markup.escape(request.form.get("page", "1"))) variant_type = Markup.escape(request.args.get("variant_type", "clinical")) category = "str" institute_obj, case_obj = institute_and_case(store, institute_id, case_name) variants_stats = store.case_variants_count(case_obj["_id"], institute_id, variant_type, False) user_obj = store.user(current_user.email) if request.method == "POST": form = controllers.populate_filters_form( store, institute_obj, case_obj, user_obj, category, request.form ) else: form = StrFiltersForm(request.args) if form.gene_panels.data == [] and variant_type == "clinical": form.gene_panels.data = controllers.case_default_panels(case_obj) # set form variant data type the first time around form.variant_type.data = variant_type # set chromosome to all chromosomes form.chrom.data = request.args.get("chrom", "") # populate filters dropdown available_filters = list(store.filters(institute_id, category)) form.filters.choices = [ (filter.get("_id"), filter.get("display_name")) for filter in available_filters ] # Populate chromosome select choices controllers.populate_chrom_choices(form, case_obj) # populate available panel choices form.gene_panels.choices = controllers.gene_panel_choices(store, institute_obj, case_obj) controllers.activate_case(store, institute_obj, case_obj, current_user) cytobands = store.cytoband_by_chrom(case_obj.get("genome_build")) query = form.data query["variant_type"] = variant_type variants_query = store.variants(case_obj["_id"], category=category, query=query).sort( [ ("str_repid", pymongo.ASCENDING), ("chromosome", pymongo.ASCENDING), ("position", pymongo.ASCENDING), ] ) result_size = store.count_variants(case_obj["_id"], query, None, category) if request.form.get("export"): return controllers.download_str_variants(case_obj, variants_query) data = controllers.str_variants( store, institute_obj, case_obj, variants_query, result_size, page ) return dict( institute=institute_obj, case=case_obj, dismiss_variant_options=DISMISS_VARIANT_OPTIONS, variant_type=variant_type, manual_rank_options=MANUAL_RANK_OPTIONS, cytobands=cytobands, form=form, page=page, filters=available_filters, expand_search=str(request.method == "POST"), result_size=result_size, total_variants=variants_stats.get(variant_type, {}).get(category, "NA"), **data, )
def variants(institute_id, case_name): """Display a list of SNV variants.""" page = int(request.form.get('page', 1)) institute_obj, case_obj = institute_and_case(store, institute_id, case_name) variant_type = request.args.get('variant_type', 'clinical') # Update filter settings if Clinical Filter was requested default_panels = [] for panel in case_obj['panels']: if panel.get('is_default'): default_panels.append(panel['panel_name']) request.form.get('gene_panels') if bool(request.form.get('clinical_filter')): clinical_filter = MultiDict({ 'variant_type': 'clinical', 'region_annotations': ['exonic','splicing'], 'functional_annotations': SEVERE_SO_TERMS, 'clinsig': [4,5], 'clinsig_confident_always_returned': True, 'gnomad_frequency': str(institute_obj['frequency_cutoff']), 'variant_type': 'clinical', 'gene_panels': default_panels }) if(request.method == "POST"): if bool(request.form.get('clinical_filter')): form = FiltersForm(clinical_filter) form.csrf_token = request.args.get('csrf_token') else: form = FiltersForm(request.form) else: form = FiltersForm(request.args) # populate available panel choices available_panels = case_obj.get('panels', []) + [ {'panel_name': 'hpo', 'display_name': 'HPO'}] panel_choices = [(panel['panel_name'], panel['display_name']) for panel in available_panels] form.gene_panels.choices = panel_choices # upload gene panel if symbol file exists if (request.files): file = request.files[form.symbol_file.name] if request.files and file and file.filename != '': log.debug("Upload file request files: {0}".format(request.files.to_dict())) try: stream = io.StringIO(file.stream.read().decode('utf-8'), newline=None) except UnicodeDecodeError as error: flash("Only text files are supported!", 'warning') return redirect(request.referrer) hgnc_symbols_set = set(form.hgnc_symbols.data) log.debug("Symbols prior to upload: {0}".format(hgnc_symbols_set)) new_hgnc_symbols = controllers.upload_panel(store, institute_id, case_name, stream) hgnc_symbols_set.update(new_hgnc_symbols) form.hgnc_symbols.data = hgnc_symbols_set # reset gene panels form.gene_panels.data = '' # update status of case if vistited for the first time if case_obj['status'] == 'inactive' and not current_user.is_admin: flash('You just activated this case!', 'info') user_obj = store.user(current_user.email) case_link = url_for('cases.case', institute_id=institute_obj['_id'], case_name=case_obj['display_name']) store.update_status(institute_obj, case_obj, user_obj, 'active', case_link) # check if supplied gene symbols exist hgnc_symbols = [] non_clinical_symbols = [] not_found_symbols = [] not_found_ids = [] if (form.hgnc_symbols.data) and len(form.hgnc_symbols.data) > 0: is_clinical = form.data.get('variant_type', 'clinical') == 'clinical' clinical_symbols = store.clinical_symbols(case_obj) if is_clinical else None for hgnc_symbol in form.hgnc_symbols.data: if hgnc_symbol.isdigit(): hgnc_gene = store.hgnc_gene(int(hgnc_symbol)) if hgnc_gene is None: not_found_ids.append(hgnc_symbol) else: hgnc_symbols.append(hgnc_gene['hgnc_symbol']) elif store.hgnc_genes(hgnc_symbol).count() == 0: not_found_symbols.append(hgnc_symbol) elif is_clinical and (hgnc_symbol not in clinical_symbols): non_clinical_symbols.append(hgnc_symbol) else: hgnc_symbols.append(hgnc_symbol) if (not_found_ids): flash("HGNC id not found: {}".format(", ".join(not_found_ids)), 'warning') if (not_found_symbols): flash("HGNC symbol not found: {}".format(", ".join(not_found_symbols)), 'warning') if (non_clinical_symbols): flash("Gene not included in clinical list: {}".format(", ".join(non_clinical_symbols)), 'warning') form.hgnc_symbols.data = hgnc_symbols # handle HPO gene list separately if form.data['gene_panels'] == ['hpo']: hpo_symbols = list(set(term_obj['hgnc_symbol'] for term_obj in case_obj['dynamic_gene_list'])) form.hgnc_symbols.data = hpo_symbols variants_query = store.variants(case_obj['_id'], query=form.data) data = {} if request.form.get('export'): document_header = controllers.variants_export_header(case_obj) export_lines = [] if form.data['chrom'] == 'MT': # Return all MT variants export_lines = controllers.variant_export_lines(store, case_obj, variants_query) else: # Return max 500 variants export_lines = controllers.variant_export_lines(store, case_obj, variants_query.limit(500)) def generate(header, lines): yield header + '\n' for line in lines: yield line + '\n' headers = Headers() headers.add('Content-Disposition','attachment', filename=str(case_obj['display_name'])+'-filtered_variants.csv') # return a csv with the exported variants return Response(generate(",".join(document_header), export_lines), mimetype='text/csv', headers=headers) data = controllers.variants(store, institute_obj, case_obj, variants_query, page) return dict(institute=institute_obj, case=case_obj, form=form, severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
def sv_variants(institute_id, case_name): """Display a list of structural variants.""" page = int(request.form.get('page', 1)) variant_type = request.args.get('variant_type', 'clinical') institute_obj, case_obj = institute_and_case(store, institute_id, case_name) form = SvFiltersForm(request.form) default_panels = [] for panel in case_obj['panels']: if panel['is_default']: default_panels.append(panel['panel_name']) request.form.get('gene_panels') if bool(request.form.get('clinical_filter')): clinical_filter = MultiDict({ 'variant_type': 'clinical', 'region_annotations': ['exonic','splicing'], 'functional_annotations': SEVERE_SO_TERMS, 'thousand_genomes_frequency': str(institute_obj['frequency_cutoff']), 'variant_type': 'clinical', 'clingen_ngi': 10, 'swegen': 10, 'size': 100, 'gene_panels': default_panels }) if(request.method == "POST"): if bool(request.form.get('clinical_filter')): form = SvFiltersForm(clinical_filter) form.csrf_token = request.args.get('csrf_token') else: form = SvFiltersForm(request.form) else: form = SvFiltersForm(request.args) available_panels = case_obj.get('panels', []) + [ {'panel_name': 'hpo', 'display_name': 'HPO'}] panel_choices = [(panel['panel_name'], panel['display_name']) for panel in available_panels] form.gene_panels.choices = panel_choices if form.data['gene_panels'] == ['hpo']: hpo_symbols = list(set(term_obj['hgnc_symbol'] for term_obj in case_obj['dynamic_gene_list'])) form.hgnc_symbols.data = hpo_symbols # update status of case if vistited for the first time if case_obj['status'] == 'inactive' and not current_user.is_admin: flash('You just activated this case!', 'info') user_obj = store.user(current_user.email) case_link = url_for('cases.case', institute_id=institute_obj['_id'], case_name=case_obj['display_name']) store.update_status(institute_obj, case_obj, user_obj, 'active', case_link) variants_query = store.variants(case_obj['_id'], category='sv', query=form.data) data = {} # if variants should be exported if request.form.get('export'): document_header = controllers.variants_export_header(case_obj) export_lines = [] # Return max 500 variants export_lines = controllers.variant_export_lines(store, case_obj, variants_query.limit(500)) def generate(header, lines): yield header + '\n' for line in lines: yield line + '\n' headers = Headers() headers.add('Content-Disposition','attachment', filename=str(case_obj['display_name'])+'-filtered_sv-variants.csv') return Response(generate(",".join(document_header), export_lines), mimetype='text/csv', headers=headers) # return a csv with the exported variants else: data = controllers.sv_variants(store, institute_obj, case_obj, variants_query, page) return dict(institute=institute_obj, case=case_obj, variant_type=variant_type, form=form, severe_so_terms=SEVERE_SO_TERMS, page=page, **data)
def cancer_sv_variants(institute_id, case_name): """Display a list of cancer structural variants.""" page = int(Markup.escape(request.form.get("page", "1"))) variant_type = Markup.escape(request.args.get("variant_type", "clinical")) category = "cancer_sv" # Define case and institute objects institute_obj, case_obj = institute_and_case(store, institute_id, case_name) variants_stats = store.case_variants_count(case_obj["_id"], institute_id, variant_type, False) if request.form.get("hpo_clinical_filter"): case_obj["hpo_clinical_filter"] = True if request.form.getlist("dismiss"): # dismiss a list of variants controllers.dismiss_variant_list( store, institute_obj, case_obj, "variant.sv_variant", request.form.getlist("dismiss"), request.form.getlist("dismiss_choices"), ) # update status of case if visited for the first time controllers.activate_case(store, institute_obj, case_obj, current_user) form = controllers.populate_sv_filters_form(store, institute_obj, case_obj, category, request) # populate filters dropdown available_filters = list(store.filters(institute_obj["_id"], category)) form.filters.choices = [ (filter.get("_id"), filter.get("display_name")) for filter in available_filters ] # Populate chromosome select choices controllers.populate_chrom_choices(form, case_obj) genome_build = "38" if "38" in str(case_obj.get("genome_build")) else "37" cytobands = store.cytoband_by_chrom(genome_build) controllers.update_form_hgnc_symbols(store, case_obj, form) variants_query = store.variants(case_obj["_id"], category=category, query=form.data) result_size = store.count_variants(case_obj["_id"], form.data, None, category) # if variants should be exported if request.form.get("export"): return controllers.download_variants(store, case_obj, variants_query) data = controllers.sv_variants( store, institute_obj, case_obj, variants_query, result_size, page ) expand_search = request.method == "POST" and request.form.get("expand_search") in [ "True", "", ] return dict( institute=institute_obj, case=case_obj, dismiss_variant_options={ **DISMISS_VARIANT_OPTIONS, **CANCER_SPECIFIC_VARIANT_DISMISS_OPTIONS, }, variant_type=variant_type, form=form, filters=available_filters, severe_so_terms=SEVERE_SO_TERMS, cancer_tier_options=CANCER_TIER_OPTIONS, manual_rank_options=MANUAL_RANK_OPTIONS, cytobands=cytobands, page=page, expand_search=expand_search, result_size=result_size, total_variants=variants_stats.get(variant_type, {}).get(category, "NA"), **data, )
def variants(institute_id, case_name): """Display a list of SNV variants.""" page = int(Markup.escape(request.form.get("page", "1"))) category = "snv" institute_obj, case_obj = institute_and_case(store, institute_id, case_name) variant_type = request.args.get("variant_type", "clinical") variants_stats = store.case_variants_count(case_obj["_id"], institute_id, variant_type, False) if request.form.get("hpo_clinical_filter"): case_obj["hpo_clinical_filter"] = True user_obj = store.user(current_user.email) if request.method == "POST": if "dismiss_submit" in request.form: # dismiss a list of variants controllers.dismiss_variant_list( store, institute_obj, case_obj, "variant.variant", request.form.getlist("dismiss"), request.form.getlist("dismiss_choices"), ) form = controllers.populate_filters_form( store, institute_obj, case_obj, user_obj, category, request.form ) else: form = FiltersForm(request.args) # set form variant data type the first time around form.variant_type.data = variant_type # set chromosome to all chromosomes form.chrom.data = request.args.get("chrom", "") if form.gene_panels.data == [] and variant_type == "clinical": form.gene_panels.data = controllers.case_default_panels(case_obj) # populate filters dropdown available_filters = list(store.filters(institute_id, category)) form.filters.choices = [ (filter.get("_id"), filter.get("display_name")) for filter in available_filters ] # Populate chromosome select choices controllers.populate_chrom_choices(form, case_obj) # populate available panel choices form.gene_panels.choices = controllers.gene_panel_choices(store, institute_obj, case_obj) # update status of case if visited for the first time controllers.activate_case(store, institute_obj, case_obj, current_user) # upload gene panel if symbol file exists if request.files: file = request.files[form.symbol_file.name] if request.files and file and file.filename != "": LOG.debug("Upload file request files: {0}".format(request.files.to_dict())) try: stream = io.StringIO(file.stream.read().decode("utf-8"), newline=None) except UnicodeDecodeError as error: flash("Only text files are supported!", "warning") return redirect(request.referrer) hgnc_symbols_set = set(form.hgnc_symbols.data) LOG.debug("Symbols prior to upload: {0}".format(hgnc_symbols_set)) new_hgnc_symbols = controllers.upload_panel(store, institute_id, case_name, stream) hgnc_symbols_set.update(new_hgnc_symbols) form.hgnc_symbols.data = hgnc_symbols_set # reset gene panels form.gene_panels.data = "" controllers.update_form_hgnc_symbols(store, case_obj, form) cytobands = store.cytoband_by_chrom(case_obj.get("genome_build")) variants_query = store.variants(case_obj["_id"], query=form.data, category=category) result_size = store.count_variants(case_obj["_id"], form.data, None, category) if request.form.get("export"): return controllers.download_variants(store, case_obj, variants_query) data = controllers.variants( store, institute_obj, case_obj, variants_query, result_size, page, query_form=form.data ) expand_search = request.method == "POST" and request.form.get("expand_search") in [ "True", "", ] return dict( institute=institute_obj, case=case_obj, form=form, filters=available_filters, manual_rank_options=MANUAL_RANK_OPTIONS, dismiss_variant_options=DISMISS_VARIANT_OPTIONS, cancer_tier_options=CANCER_TIER_OPTIONS, severe_so_terms=SEVERE_SO_TERMS, cytobands=cytobands, page=page, expand_search=expand_search, result_size=result_size, total_variants=variants_stats.get(variant_type, {}).get(category, "NA"), **data, )