def gene_edit(panel_id, hgnc_id): """Edit additional information about a panel gene.""" panel_obj = store.panel(panel_id) hgnc_gene = store.hgnc_gene(hgnc_id) panel_gene = controllers.existing_gene(store, panel_obj, hgnc_id) form = PanelGeneForm() transcript_choices = [] for transcript in hgnc_gene['transcripts']: if transcript.get('refseq_id'): refseq_id = transcript.get('refseq_id') transcript_choices.append((refseq_id, refseq_id)) form.disease_associated_transcripts.choices = transcript_choices if form.validate_on_submit(): action = 'edit' if panel_gene else 'add' info_data = form.data.copy() if 'csrf_token' in info_data: del info_data['csrf_token'] store.add_pending(panel_obj, hgnc_gene, action=action, info=info_data) return redirect(url_for('.panel', panel_id=panel_id)) if panel_gene: for field_key in ['disease_associated_transcripts', 'reduced_penetrance', 'mosaicism', 'inheritance_models', 'database_entry_version', 'comment']: form_field = getattr(form, field_key) if not form_field.data: panel_value = panel_gene.get(field_key) if panel_value is not None: form_field.process_data(panel_value) return dict(panel=panel_obj, form=form, gene=hgnc_gene, panel_gene=panel_gene)
def panel(panel_id): """Display (and add pending updates to) a specific gene panel.""" panel_obj = store.gene_panel(panel_id) or store.panel(panel_id) if request.method == 'POST': raw_hgnc_id = request.form['hgnc_id'] if '|' in raw_hgnc_id: raw_hgnc_id = raw_hgnc_id.split(' | ', 1)[0] hgnc_id = int(raw_hgnc_id) action = request.form['action'] gene_obj = store.hgnc_gene(hgnc_id) if gene_obj is None: flash("HGNC id not found: {}".format(hgnc_id)) return redirect(request.referer) if action == 'add': panel_gene = controllers.existing_gene(store, panel_obj, hgnc_id) if panel_gene: flash("gene already in panel: {}".format(panel_gene['symbol']), 'warning') else: # ask user to fill-in more information about the gene return redirect( url_for('.gene_edit', panel_id=panel_id, hgnc_id=hgnc_id)) elif action == 'delete': log.debug("marking gene to be deleted: %s", hgnc_id) store.add_pending(panel_obj, gene_obj, action='delete') data = controllers.panel(store, panel_obj) if request.args.get('case_id'): data['case'] = store.case(request.args['case_id']) if request.args.get('institute_id'): data['institute'] = store.institute(request.args['institute_id']) return data
def gene_variants(institute_id): """Display a list of SNV variants.""" page = int(request.form.get('page', 1)) institute_obj = institute_and_case(store, institute_id) # populate form, conditional on request method if (request.method == "POST"): form = GeneVariantFiltersForm(request.form) else: form = GeneVariantFiltersForm(request.args) variant_type = form.data.get('variant_type', 'clinical') # check if supplied gene symbols exist hgnc_symbols = [] non_clinical_symbols = [] not_found_symbols = [] not_found_ids = [] data = {} 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 log.debug("query {}".format(form.data)) variants_query = store.gene_variants(query=form.data, category='snv', variant_type=variant_type) data = controllers.gene_variants(store, variants_query, page) return dict(institute=institute_obj, form=form, page=page, **data)
def gene_edit(panel_id, hgnc_id): """Edit additional information about a panel gene.""" panel_obj = store.panel(panel_id) hgnc_gene = store.hgnc_gene(hgnc_id) panel_gene = controllers.existing_gene(store, panel_obj, hgnc_id) form = PanelGeneForm() transcript_choices = [] for transcript in hgnc_gene["transcripts"]: if transcript.get("refseq_id"): refseq_id = transcript.get("refseq_id") transcript_choices.append((refseq_id, refseq_id)) # collect even refseq version provided by user for this transcript (might have a version) if panel_obj.get("genes"): genes_dict = {gene_obj["symbol"]: gene_obj for gene_obj in panel_obj["genes"]} gene_obj = genes_dict.get(hgnc_gene["hgnc_symbol"]) if gene_obj: for transcript in gene_obj.get("disease_associated_transcripts", []): if (transcript, transcript) not in transcript_choices: transcript_choices.append((transcript, transcript)) form.disease_associated_transcripts.choices = transcript_choices if form.validate_on_submit(): action = "edit" if panel_gene else "add" info_data = form.data.copy() if "csrf_token" in info_data: del info_data["csrf_token"] if info_data["custom_inheritance_models"] != "": info_data["custom_inheritance_models"] = info_data[ "custom_inheritance_models" ].split(",") store.add_pending(panel_obj, hgnc_gene, action=action, info=info_data) return redirect(url_for(".panel", panel_id=panel_id)) if panel_gene: form.custom_inheritance_models.data = ", ".join( panel_gene.get("custom_inheritance_models", []) ) for field_key in [ "disease_associated_transcripts", "reduced_penetrance", "mosaicism", "inheritance_models", "custom_inheritance_models", "database_entry_version", "comment", ]: form_field = getattr(form, field_key) if not form_field.data: panel_value = panel_gene.get(field_key) if panel_value is not None: form_field.process_data(panel_value) return dict(panel=panel_obj, form=form, gene=hgnc_gene, panel_gene=panel_gene)
def gene_variants(institute_id): """Display a list of SNV variants.""" page = int(request.form.get('page', 1)) institute_obj = institute_and_case(store, institute_id) # populate form, conditional on request method if(request.method == "POST"): form = GeneVariantFiltersForm(request.form) else: form = GeneVariantFiltersForm(request.args) variant_type = form.data.get('variant_type', 'clinical') # check if supplied gene symbols exist hgnc_symbols = [] non_clinical_symbols = [] not_found_symbols = [] not_found_ids = [] data = {} 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 log.debug("query {}".format(form.data)) variants_query = store.gene_variants(query=form.data, category='snv', variant_type=variant_type) data = controllers.gene_variants(store, variants_query, page) return dict(institute=institute_obj, form=form, page=page, **data)
def panel(panel_id): """Display (and add pending updates to) a specific gene panel.""" panel_obj = store.gene_panel(panel_id) or store.panel(panel_id) if request.method == "POST": if request.form.get("update_description"): panel_obj["description"] = request.form["panel_description"] if panel_write_granted(panel_obj, current_user): store.update_panel(panel_obj=panel_obj) else: flash( "Permission denied: please ask a panel maintainer or admin for help.", "danger", ) return redirect(url_for("panels.panel", panel_id=panel_obj["_id"])) raw_hgnc_id = request.form["hgnc_id"] if "|" in raw_hgnc_id: raw_hgnc_id = raw_hgnc_id.split(" | ", 1)[0] hgnc_id = 0 try: hgnc_id = int(raw_hgnc_id) except ValueError: flash("Provided HGNC is not valid : '{}'".format(raw_hgnc_id), "danger") return redirect(request.referrer) action = request.form["action"] gene_obj = store.hgnc_gene(hgnc_id) if gene_obj is None: flash("HGNC id not found: {}".format(hgnc_id), "warning") return redirect(request.referrer) if action == "add": panel_gene = controllers.existing_gene(store, panel_obj, hgnc_id) if panel_gene: flash( "gene already in panel: {}".format(panel_gene["symbol"]), "warning" ) else: # ask user to fill-in more information about the gene return redirect( url_for(".gene_edit", panel_id=panel_id, hgnc_id=hgnc_id) ) elif action == "delete": LOG.debug("marking gene to be deleted: %s", hgnc_id) panel_obj = store.add_pending(panel_obj, gene_obj, action="delete") data = controllers.panel(store, panel_obj) if request.args.get("case_id"): data["case"] = store.case(request.args["case_id"]) if request.args.get("institute_id"): data["institute"] = store.institute(request.args["institute_id"]) return data
def gene(hgnc_id=None, hgnc_symbol=None): """Render information about a gene.""" if hgnc_symbol: query = store.hgnc_genes(hgnc_symbol) if query.count() < 2: gene_obj = query.first() else: return redirect(url_for('.genes', query=hgnc_symbol)) else: gene_obj = store.hgnc_gene(hgnc_id) if gene_obj is None: return abort(404) controllers.gene(gene_obj) return dict(gene=gene_obj)
def update_HGNC_symbols(store, variant_genes, genome_build): """Update the HGNC symbols if they are not set Returns: gene_object()""" if variant_genes is not None: for gene_obj in variant_genes: # If there is no hgnc id there is nothin we can do if not gene_obj["hgnc_id"]: continue # Else we collect the gene object and check the id if gene_obj.get("hgnc_symbol") is None or gene_obj.get("description") is None: hgnc_gene = store.hgnc_gene(gene_obj["hgnc_id"], build=genome_build) if not hgnc_gene: continue gene_obj["hgnc_symbol"] = hgnc_gene["hgnc_symbol"] gene_obj["description"] = hgnc_gene["description"]
def tx_choices(hgnc_id, panel_obj): """Collect transcripts from a gene both in build 37 and 38 Args: hgnc_id(int): a gene HGNC ID panel_obj(dict): a gene panel dictionary representation Returns: transcript_choices(list) a list with the options for a form select field """ transcript_choices = [] hgnc_gene = None for build in ["37", "38"]: build_specific_hgnc_gene = store.hgnc_gene(hgnc_identifier=hgnc_id, build=build) if build_specific_hgnc_gene is None: continue hgnc_gene = build_specific_hgnc_gene for transcript in build_specific_hgnc_gene["transcripts"]: if transcript.get("refseq_id"): refseq_id = transcript.get("refseq_id") transcript_choices.append( (refseq_id, f"{refseq_id} (build {build})")) # collect even refseq version provided by user for this transcript (might have a version) if panel_obj.get("genes"): genes_dict = { gene_obj["symbol"]: gene_obj for gene_obj in panel_obj["genes"] } gene_obj = genes_dict.get(hgnc_gene["hgnc_symbol"]) if gene_obj: for transcript in gene_obj.get("disease_associated_transcripts", []): if (transcript, transcript) not in transcript_choices: transcript_choices.append( (transcript, f"{transcript} (previous choice)")) return transcript_choices
def panel(panel_id): """Display (and add pending updates to) a specific gene panel.""" panel_obj = store.gene_panel(panel_id) or store.panel(panel_id) if request.method == 'POST': raw_hgnc_id = request.form['hgnc_id'] if '|' in raw_hgnc_id: raw_hgnc_id = raw_hgnc_id.split(' | ', 1)[0] hgnc_id = 0 try: hgnc_id = int(raw_hgnc_id) except: flash("Provided HGNC is not valid : '{}'". format(raw_hgnc_id), 'danger') return redirect(request.referrer) action = request.form['action'] gene_obj = store.hgnc_gene(hgnc_id) if gene_obj is None: flash("HGNC id not found: {}".format(hgnc_id), 'warning') return redirect(request.referrer) if action == 'add': panel_gene = controllers.existing_gene(store, panel_obj, hgnc_id) if panel_gene: flash("gene already in panel: {}".format(panel_gene['symbol']), 'warning') else: # ask user to fill-in more information about the gene return redirect(url_for('.gene_edit', panel_id=panel_id, hgnc_id=hgnc_id)) elif action == 'delete': log.debug("marking gene to be deleted: %s", hgnc_id) panel_obj = store.add_pending(panel_obj, gene_obj, action='delete') data = controllers.panel(store, panel_obj) if request.args.get('case_id'): data['case'] = store.case(request.args['case_id']) if request.args.get('institute_id'): data['institute'] = store.institute(request.args['institute_id']) return 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 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 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.get('is_default') and panel['is_default'] is True) or ('default_panels' in case_obj and panel['panel_id'] in case_obj['default_panels']): 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 # 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) # 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 gene_variants(institute_id): """Display a list of SNV variants.""" page = int(request.form.get("page", 1)) institute_obj = institute_and_case(store, institute_id) # populate form, conditional on request method if request.method == "POST": form = GeneVariantFiltersForm(request.form) else: form = GeneVariantFiltersForm(request.args) if form.variant_type.data == []: form.variant_type.data = ["clinical"] variant_type = form.data.get("variant_type") # check if supplied gene symbols exist hgnc_symbols = [] non_clinical_symbols = [] not_found_symbols = [] not_found_ids = [] data = {} 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_find_one(hgnc_symbol) is None: not_found_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", ) if hgnc_symbols == []: # If there are not genes to search, return to previous page with a warning flash("No valid gene provided for variant search.", "warning") return redirect(request.referrer) form.hgnc_symbols.data = hgnc_symbols variants_query = store.gene_variants(query=form.data, institute_id=institute_id, category="snv", variant_type=variant_type) result_size = store.count_gene_variants(query=form.data, institute_id=institute_id, category="snv", variant_type=variant_type) data = controllers.gene_variants(store, variants_query, result_size, institute_id, page) return dict(institute=institute_obj, form=form, page=page, **data)
def gene_variants(institute_id): """Display a list of SNV variants.""" page = int(request.form.get("page", 1)) institute_obj = institute_and_case(store, institute_id) # populate form, conditional on request method if request.method == "POST": form = GeneVariantFiltersForm(request.form) else: form = GeneVariantFiltersForm(request.args) if form.variant_type.data == []: form.variant_type.data = ["clinical"] variant_type = form.data.get("variant_type") # check if supplied gene symbols exist hgnc_symbols = [] non_clinical_symbols = [] not_found_symbols = [] not_found_ids = [] data = {} 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 LOG.debug("query {}".format(form.data)) variants_query = store.gene_variants( query=form.data, institute_id=institute_id, category="snv", variant_type=variant_type, ) data = controllers.gene_variants(store, variants_query, institute_id, page) return dict(institute=institute_obj, form=form, 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 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 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)