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, )
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 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 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( user: str, case_id: str, status: list, older_than: int, analysis_type: list, rank_threshold: int, variants_threshold: int, keep_ctg: list, dry_run: bool, ) -> None: """Delete variants for one or more cases""" user_obj = store.user(user) if user_obj is None: click.echo(f"Could not find a user with email '{user}' in database") return total_deleted = 0 items_name = "deleted variants" if dry_run: click.echo("--------------- DRY RUN COMMAND ---------------") items_name = "estimated deleted variants" else: click.confirm( "Variants are going to be deleted from database. Continue?", abort=True) case_query = store.build_case_query(case_id, status, older_than, analysis_type) # Estimate the average size of a variant document in database avg_var_size = store.collection_stats("variant").get("avgObjSize", 0) # in bytes # Get all cases where case_query applies n_cases = store.case_collection.count_documents(case_query) cases = store.cases(query=case_query) filters = ( f"Rank-score threshold:{rank_threshold}, case n. variants threshold:{variants_threshold}." ) click.echo("\t".join(DELETE_VARIANTS_HEADER)) for nr, case in enumerate(cases, 1): case_id = case["_id"] institute_id = case["owner"] case_n_variants = store.variant_collection.count_documents( {"case_id": case_id}) # Skip case if user provided a number of variants to keep and this number is less than total number of case variants if variants_threshold and case_n_variants < variants_threshold: continue # Get evaluated variants for the case that haven't been dismissed case_evaluated = store.evaluated_variants(case_id=case_id, institute_id=institute_id) evaluated_not_dismissed = [ variant["_id"] for variant in case_evaluated if "dismiss_variant" not in variant ] # Do not remove variants that are either pinned, causative or evaluated not dismissed variants_to_keep = (case.get("suspects", []) + case.get("causatives", []) + evaluated_not_dismissed or []) variants_query = store.delete_variants_query(case_id, variants_to_keep, rank_threshold, keep_ctg) if dry_run: # Just print how many variants would be removed for this case remove_n_variants = store.variant_collection.count_documents( variants_query) total_deleted += remove_n_variants click.echo("\t".join([ str(nr), str(n_cases), case["owner"], case["display_name"], case_id, case.get("track", ""), str(case["analysis_date"]), case.get("status", ""), str(case.get("is_research", "")), str(case_n_variants), str(remove_n_variants), ])) continue # delete variants specified by variants_query result = store.variant_collection.delete_many(variants_query) total_deleted += result.deleted_count click.echo("\t".join([ str(nr), str(n_cases), case["owner"], case["display_name"], case_id, case.get("track", ""), str(case["analysis_date"]), case.get("status", ""), str(case.get("is_research", "")), str(case_n_variants), str(result.deleted_count), ])) # Create event in database institute_obj = store.institute(case["owner"]) with current_app.test_request_context("/cases"): url = url_for( "cases.case", institute_id=institute_obj["_id"], case_name=case["display_name"], ) store.remove_variants_event( institute=institute_obj, case=case, user=user_obj, link=url, content=filters, ) # Update case variants count store.case_variants_count(case_id, institute_obj["_id"], True) click.echo(f"Total {items_name}: {total_deleted}") click.echo( f"Estimated space freed (GB): {round((total_deleted * avg_var_size) / BYTES_IN_ONE_GIGABYTE, 4)}" )